I'm relatively new to both C and bitwise operations and I'm having trouble with an assignment I've been given in my class. A majority of the code has been given to me, but I've been having issues figuring out a part pertaining to bitwise operations. Once I figure this part out, I'll be golden. I hope that someone can help!
Here is the excerpt from my assignment:
You will need to use 8 bytes of an image to hide one byte of information (remember that only LSBs of the cover image can be modified). You will use the rest of the 16 bytes of the cover image to embed 16 bits of b.size (two least significant bytes of the size field for the binary data), next 32 bytes of the cover will be used to embed the file extension
for the payload file, and after that you will use 8*b.size bytes to embed the payload (b.data).
What this program is doing is stenography of an image, and I have to modify the least significant bits of the image read in using data from a file that I created. Like I said, all of the code for that is already written. I just can't figure out how to modify the LSBs. Any help would be greatly appreciated!!!
The functions I have to use for reformatting the LSBs are as follows:
byte getlsbs(byte *b);
void setlsbs(byte *b, byte b0);
This is what I've attempted thus far:
/* In main function */
b0 = getlsbs(&img.gray[0])
/* Passing arguments */
byte getlsbs(byte *b)
{
byte b0;
b0[0] = b >> 8;
return b0;
}
I'm honestly at a complete loss. I've been working on this all night and I still barely have made headway.
To set LSB of b to 1:
b |= 1;
To set LSB of b to 0:
b &= 0xFE;
Here is an idea how the functions could be implemented. This code is not tested.
byte getlsbs(byte *b)
{
byte result = 0;
for (int i = 0; i < 8; ++i)
{
result >>= 1;
if (*b & 1)
result |= 0x80;
++b;
}
return result;
}
void setlsbs(byte *b, byte b0)
{
for (int i = 0; i < 8; ++i)
{
if (b0 & 1)
*b |= 1;
else
*b &= 0xFE;
++b;
b0 >>= 1;
}
}
Related
I am dealing with a situation where I need to send/receive data via a TCP/IP socket between myself (client) and a server. The message structure is proprietary, but is basically arrays of uint32_t. I am tasked with handling the Endian conversion on my end. As the client, I am operating in Windows (little endian). The server is operating in VxWorks environment (big endian). Therefor, I need to convert data I send from little to big, and data I receive from big to little.
Now, I am aware that endianness refers to BYTE order within a word. So, I created a function that would do the byte swapping for each uint32_t word in a given array. See below.
void convertEndian(uint32_t inputData[], int size)
{
uint32_t b1, b2, b3, b4;
for (int i = 0; i < size; ++i)
{
b1 = (inputData[i] & 0xFF000000) >> 24;
b2 = (inputData[i] & 0x00FF0000) >> 8;
b3 = (inputData[i] & 0x0000FF00) << 8;
b4 = (inputData[i] & 0x000000FF) << 24;
inputData[i] = b1 | b2 | b3 | b4;
}
}
This approach is fine for certain message types I'll be dealing with, where each word is defined by an entire uint32_t value. However, some messages have many words that have their own unique bit fields. Below is an example of one:
Struct test
{
Unsigned int var1 : 16;
Unsigned int var2 : 12;
Unsigned int var3 : 1;
Unsigned int var4 : 1;
Unsigned int var5 : 1;
Unsigned int var6 : 1;
}
How do I implement endian conversion for such cases? There is one message type for example, where I will be receiving an array of about 32 words of uint32_t and each of those words has its own set of bit fields representing various things.
I guess my only choice is to mask/shift for each word as needed. But then I will pretty much have to make 32 unique functions for each word. It seems very labor intensive.
Any suggestions would be appreciated.
This is hopefully without too many assumptions.
Totally untested, humour not marked.
static_assert(sizeof(test) == sizeof (uint32_t), "Houston we have a problem");
template < typename NetOrHost>
void convertEndian(uint32_t inputData[], int size) {
for (int i = 0; i < size; ++i)
inputData[i] = NetOrHost(inputData[i]);
}
// or simply use
std::for_each(inputData, inputData+size, htonl /* ntohl for the other way */); // this part needs a bit of testing ...
// Now encoding the test struct
// Using https://stackoverflow.com/a/20194422/4013258 BitCount
// or just use magic values, *hands OP a foot-gun*
// Once only
std::array<int, 6> bits; // todo make this constexpr
bits[0] = BitCount(test.var1);
bits[1] = BitCount(test.var2);
etc ...
static_assert(std::accumulate(bits.begin(), bits.end(), 0) == 32, "Preconditions violated");
// this goes well because we know that it fits in a 32-bit unsigned integer.
uint32_t encoded = 0;
encoded = test.var1;
encoded <<= bits[1];
encoded += test.var2;
encoded <<= bits[2];
encoded += test.var3;
etc.
// To decode
uint32_t decode = inputData[i];
test.var6 = decode & ((1 << bits[5])-1); // or make a mask array
decode >>= bits[5];
etc.
This would be a lot easier with reflection ...
I am trying to create a CRC-15 check in c and the output is never correct for each line of the file. I am trying to output the CRC for each line cumulatively next to each line. I use: #define POLYNOMIAL 0xA053 for the divisor and text for the dividend. I need to represent numbers as 32-bit unsigned integers. I have tried printing out the hex values to keep track and flipping different shifts around. However, I just can't seem to figure it out! I have a feeling it has something to do with the way I am padding things. Is there a flaw to my logic?
The CRC is to be represented in four hexadecimal numbers, that sequence will have four leading 0's. For example, it will look like 0000xxxx where the x's are the hexadecimal digits. The polynomial I use is 0xA053.
I thought about using a temp variable and do 4 16 bit chunks of code per line every XOR, however, I'm not quite sure how I could use shifts to accomplish this so I settled for a checksum of the letters on the line and then XORing that to try to calculate the CRC code.
I am testing my code using the following input and padding with . until the string is of length 504 because that is what the pad character needs to be via the requirements given:
"This is the lesson: never give in, never give in, never, never, never, never - in nothing, great or small, large or petty - never give in except to convictions of honor and good sense. Never yield to force; never yield to the apparently overwhelming might of the enemy."
The CRC of the first 64 char line ("This is the lesson: never give in, never give in, never, never,) is supposed to be 000015fa and I am getting bfe6ec00.
My logic:
In CRCCalculation I add each character to a 32-bit unsigned integer and after 64 (the length of one line) I send it into the XOR function.
If it the top bit is not 1, I shift the number to the left one
causing 0s to pad the right and loop around again.
If the top bit is 1, I XOR the dividend with the divisor and then shift the dividend to the left one.
After all calculations are done, I return the dividend shifted to the left four ( to add four zeros to the front) to the calculation function
Add result to the running total of the result
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#define POLYNOMIAL 0xA053
void crcCalculation(char *text, int length)
{
int i;
uint32_t dividend = atoi(text);
uint32_t result;
uint32_t sumText = 0;
// Calculate CRC
printf("\nCRC 15 calculation progress:\n");
i = length;
// padding
if(i < 504)
{
for(; i!=504; i++)
{
// printf("i is %d\n", i);
text[i] = '.';
}
}
// Try calculating by first line of crc by summing the values then calcuating, then add in the next line
for (i = 0; i < 504; i++)
{
if(i%64 == 0 && i != 0)
{
result = XOR(POLYNOMIAL, sumText);
printf(" - %x\n",result);
}
sumText +=(uint32_t)text[i];
printf("%c", text[i]);
}
printf("\n\nCRC15 result : %x\n", result);
}
uint32_t XOR(uint32_t divisor, uint32_t dividend)
{
uint32_t divRemainder = dividend;
uint32_t currentBit;
// Note: 4 16 bit chunks
for(currentBit = 32; currentBit > 0; --currentBit)
{
// if topbit is 1
if(divRemainder & 0x80)
{
//divRemainder = (divRemainder << 1) ^ divisor;
divRemainder ^= divisor;
printf("%x %x\n", divRemainder, divisor);
}
// else
// divisor = divisor >> 1;
divRemainder = (divRemainder << 1);
}
//return divRemainder; , have tried shifting to right and left, want to add 4 zeros to front so >>
//return divRemainder >> 4;
return divRemainder >> 4;
}
The first issue I see is the top bit check, it should be:
if(divRemainder & 0x8000)
The question doesn't state if the CRC is bit reflected (xor data into low order bits of CRC, right shift for cycle) or not (xor data into high order bits of CRC, left shift for cycle), so I can't offer help for the rest of the code.
The question doesn't state the initial value of CRC (0x0000 or 0x7fff), or if the CRC is post complemented.
The logic for a conventional CRC is:
xor a byte of data into the CRC (upper or lower bits)
cycle the CRC 8 times (or do a table lookup)
After generating the CRC for an entire message, the CRC can be appended to the message. If a CRC is generated for a message with the appended CRC and there are no errors, the CRC will be zero (or a constant value if the CRC is post complemented).
here is a typical CRC16, extracted from: <www8.cs.umu.se/~isak/snippets/crc-16.c>
#define POLY 0x8408
/*
// 16 12 5
// this is the CCITT CRC 16 polynomial X + X + X + 1.
// This works out to be 0x1021, but the way the algorithm works
// lets us use 0x8408 (the reverse of the bit pattern). The high
// bit is always assumed to be set, thus we only use 16 bits to
// represent the 17 bit value.
*/
unsigned short crc16(char *data_p, unsigned short length)
{
unsigned char i;
unsigned int data;
unsigned int crc = 0xffff;
if (length == 0)
return (~crc);
do
{
for (i=0, data=(unsigned int)0xff & *data_p++;
i < 8;
i++, data >>= 1)
{
if ((crc & 0x0001) ^ (data & 0x0001))
crc = (crc >> 1) ^ POLY;
else crc >>= 1;
}
} while (--length);
crc = ~crc;
data = crc;
crc = (crc << 8) | (data >> 8 & 0xff);
return (crc);
}
Since you want to calculate a CRC15 rather than a CRC16, the logic will be more complex as cannot work with whole bytes, so there will be a lot of bit shifting and ANDing to extract the desire 15 bits.
Note: the OP did not mention if the initial value of the CRC is 0x0000 or 0x7FFF, nor if the result is to be complemented, nor certain other criteria, so this posted code can only be a guide.
What is the best way to implement a bitwise memmove? The method should take an additional destination and source bit-offset and the count should be in bits too.
I saw that ARM provides a non-standard _membitmove, which does exactly what I need, but I couldn't find its source.
Bind's bitset includes isc_bitstring_copy, but it's not efficient
I'm aware that the C standard library doesn't provide such a method, but I also couldn't find any third-party code providing a similar method.
Assuming "best" means "easiest", you can copy bits one by one. Conceptually, an address of a bit is an object (struct) that has a pointer to a byte in memory and an index of a bit in the byte.
struct pointer_to_bit
{
uint8_t* p;
int b;
};
void membitmovebl(
void *dest,
const void *src,
int dest_offset,
int src_offset,
size_t nbits)
{
// Create pointers to bits
struct pointer_to_bit d = {dest, dest_offset};
struct pointer_to_bit s = {src, src_offset};
// Bring the bit offsets to range (0...7)
d.p += d.b / 8; // replace division by right-shift if bit offset can be negative
d.b %= 8; // replace "%=8" by "&=7" if bit offset can be negative
s.p += s.b / 8;
s.b %= 8;
// Determine whether it's OK to loop forward
if (d.p < s.p || d.p == s.p && d.b <= s.b)
{
// Copy bits one by one
for (size_t i = 0; i < nbits; i++)
{
// Read 1 bit
int bit = (*s.p >> s.b) & 1;
// Write 1 bit
*d.p &= ~(1 << d.b);
*d.p |= bit << d.b;
// Advance pointers
if (++s.b == 8)
{
s.b = 0;
++s.p;
}
if (++d.b == 8)
{
d.b = 0;
++d.p;
}
}
}
else
{
// Copy stuff backwards - essentially the same code but ++ replaced by --
}
}
If you want to write a version optimized for speed, you will have to do copying by bytes (or, better, words), unroll loops, and handle a number of special cases (memmove does that; you will have to do more because your function is more complicated).
P.S. Oh, seeing that you call isc_bitstring_copy inefficient, you probably want the speed optimization. You can use the following idea:
Start copying bits individually until the destination is byte-aligned (d.b == 0). Then, it is easy to copy 8 bits at once, doing some bit twiddling. Do this until there are less than 8 bits left to copy; then continue copying bits one by one.
// Copy 8 bits from s to d and advance pointers
*d.p = *s.p++ >> s.b;
*d.p++ |= *s.p << (8 - s.b);
P.P.S Oh, and seeing your comment on what you are going to use the code for, you don't really need to implement all the versions (byte/halfword/word, big/little-endian); you only want the easiest one - the one working with words (uint32_t).
Here is a partial implementation (not tested). There are obvious efficiency and usability improvements.
Copy n bytes from src to dest (not overlapping src), and shift bits at dest rightwards by bit bits, 0 <= bit <= 7. This assumes that the least significant bits are at the right of the bytes
void memcpy_with_bitshift(unsigned char *dest, unsigned char *src, size_t n, int bit)
{
int i;
memcpy(dest, src, n);
for (i = 0; i < n; i++) {
dest[i] >> bit;
}
for (i = 0; i < n; i++) {
dest[i+1] |= (src[i] << (8 - bit));
}
}
Some improvements to be made:
Don't overwrite first bit bits at beginning of dest.
Merge loops
Have a way to copy a number of bits not divisible by 8
Fix for >8 bits in a char
I've recently decided to undertake an SMS project for sending and receiving SMS though a mobile.
The data is sent in PDU format - I am required to change ASCII characters to 7 bit GSM alphabet characters. To do this I've come across several examples, such as http://www.dreamfabric.com/sms/hello.html
This example shows Rightmost bits of the second septet, being inserted into the first septect, to create an octect.
Bitwise shifts do not cause this to happen, as >> will insert to the left, and << to the right. As I understand it, I need some kind of bitwise rotate to create this - can anyone tell me how to move bits from the right handside and insert them on the left?
Thanks,
Here is a quick algorithm to do that:
int b1, bnext;
int mod;
int pand;
char *b; // this is your byte buffer, with message content
int blen; // this is your byte buffer length
char sb[160];
int totchars = 0;
b1 = bnext = 0;
for (int i=0; i < blen; i++) {
mod = i%7;
pand = 0xff >> (mod + 1);
b1 = ((b[i] & pand) << mod) | bnext;
bnext = (0xff & b[i]) >> (7 - mod);
sb[totchars++] = (char)b1;
if (mod == 6) {
sb[totchar++] = (char)bnext;
bnext = 0;
}
}
sb[totchar] = 0;
It will convert 7bit compressed buffers to regular ASCII char arrays in C.
can anyone tell me how to move bits
from the right handside and insert
them on the left?
There are indirect ways in C but I'd simply do it like this:
void main()
{
int x = 0xBAADC0DE;
__asm
{
mov eax, x;
rol eax, 1;
}
}
This will rotate (not shift!) the bits to the left (one step).
"ror" will rotate to the right.
I'm doing a steganography project where I read in bytes from a ppm file and add the least significant bit to an array. So once 8 bytes are read in, I would have 8 bits in my array, which should equal some character in a hidden message. Is there an easy way to convert an array of 0's and 1's into an ascii value? For example, the array: char bits[] = {0,1,1,1,0,1,0,0} would equal 't'. Plain C
Thanks for all the answers. I'm gonna give some of these a shot.
A simple for loop would work - something like
unsigned char ascii = 0;
unsigned char i;
for(i = 0; i < 8; i++)
ascii |= (bits[7 - i] << i);
There might be a faster way to do this, but this is a start at least.
I wouldn't store the bits in an array -- I'd OR them with a char.
So you start off with a char value of 0: char bit = 0;
When you get the first bit, OR it with what you have: bit |= bit_just_read;
Keep doing that with each bit, shifting appropriately; i.e., after you get the next bit, do bit |= (next_bit << 1);. And so forth.
After you read your 8 bits, bit will be the appropriate ASCII value, and you can print it out or do whatever with it you want to do.
I agree with mipadi, don't bother storing in an array first, that's kind of pointless. Since you have to loop or otherwise keep track of the array index while reading it in, you might as well do it in one go. Something like this, perhaps?
bits = 0;
for ( i = 0; i < 8; ++i ) {
lsb = get_byte_from_ppm_somehow() & 0x01;
bits <<= 1 | lsb;
}
As long as the bit endian is correct, this should work and compile down pretty small.
If the bit endian is backwards then you should be able to change the initial value of mask to 1, the mask shift to <<= , and you might need to have (0x0ff & mask) as the do{}while conditional if your compiler doesn't do what it's supposed to with byte sized variables.
Don't forget to do something for the magic functions that I included where I didn't know what you wanted or how you did something
#include <stdint.h> // needed for uint8_t
...
uint8_t acc, lsb, mask;
uint8_t buf[SOME_SIZE];
size_t len = 0;
while (is_there_more_ppm_data()) {
acc = 0;
mask = 0x80; // This is the high bit
do {
if (!is_there_more() ) {
// I don't know what you think should happen if you run out on a non-byte boundary
EARLY_END_OF_DATA();
break;
}
lsb = 1 & get_next_ppm_byte();
acc |= lsb ? mask : 0; // You could use an if statement
mask >>= 1;
} while (mask);
buf[len] = acc; // NOTE: I didn't worry about the running off the end of the buff, but you should.
len++;
}