I'm trying to encode_char_in C that replace the bit of even index between the odd bit index, like this
'W' = 57h = 0101_0111
ABh = 1010_1011
and because char in C may become to negative number, I can't switch between the bits (only in signed char — it works).
It gave me another value
in this code below.
#include <stdio.h>
#include <limits.h>
#define TRUE 1
#define ONE 1
char codeBinPair(char str);
void main()
{
char str[2] = { 182,NULL };
unsigned char ch = 'W';
printf("ch = %x\n", ch);
ch = codeBinPair(ch);
printf("ch = %x\n", ch);
ch = codeBinPair(ch);
printf("ch = %x\n", ch);
}
char codeBinPair(char str)
{
int idx = 0;
char ch1 = str, ch2 = 0, mask = ONE;
while (TRUE)
{
mask <<= ONE;
mask &= ch1;
mask >>= ONE;
ch2 |= mask;
// Initialize the mask
mask = ONE;
mask <<= idx;
mask &= ch1;
mask <<= ONE;
ch2 |= mask;
// Index next loop we want to replace
idx += 2;
// If We Finish whole Byte
if (idx == CHAR_BIT)
return ch2;
// Initialize the mask
mask = ONE;
mask <<= idx;
}
}
Change all the char in codeBinPair to unsigned char.
unsigned char codeBinPair(unsigned char str)
{
int idx = 0;
unsigned char ch1 = str, ch2 = 0, mask = ONE;
while (TRUE)
{
mask <<= ONE;
mask &= ch1;
mask >>= ONE;
ch2 |= mask;
// Initialize the mask
mask = ONE;
mask <<= idx;
mask &= ch1;
mask <<= ONE;
ch2 |= mask;
// Index next loop we want to replace
idx += 2;
// If we finish whole byte
if (idx == CHAR_BIT)
return ch2;
// Initialize the mask
mask = ONE;
mask <<= idx;
}
}
char codeBinPair(char str)
{
int idx = CHAR_BIT - 1;
char mask = 1;
char maskA = 0;
char maskB = 0;
// str = 'W'
while (idx--) // Loop 7 times = 7 bits in char
{
//To Replace the odd bits
maskA |= mask & str;
mask <<= 1;
//To Replace the even bits
maskB |= mask & str;
mask <<= 1;
}
// to shift ths bits of 2 masks
maskA <<= 1;
maskB >>= 1;
// Subtraction between the 2 masks will give the encoded
return maskA - maskB;}
}
Related
Is there a good way to parse 32 bit values out of a string? the following function does not throw the correct value and I don't know how to fix it. the value should be 170
unsigned int getvalue(const char *data, int offset)
{
unsigned int payload = 0;
for (unsigned char i = 0; i < 4; i++)
{
payload <<= 8;
payload |= data[i + offset];
}
return payload;
}
int value = 0x00aa;
unsigned char b1 = (value & 0xFF);
unsigned char b2 = ((value >> 8) & 0xFF);
unsigned char b3 = ((value >> 16) & 0xFF);
unsigned char b4 = ((value >> 24) & 0xFF);
int number = (b4 << 24) + (b3 << 16) + (b2 << 8) + b1;
printf("value is: %d\n", number); // value is: 170 correct
char payload[] = "000000aa";
int value2 = getvalue(payload, 0);
printf("value is: %dn", value2); // value is: 808464432n Not correct
if you want to convert C string containing hexadecimal number) to its integer value:
unsigned long long conv(const char *str)
{
const char digits[] = "01234567890ABCDEF";
unsigned long long result = 0;
char *ref;
while(*str)
{
result *= 16;
ref = strchr(digits, toupper((unsigned char)*str));
if(ref)
{
result += ref - digits;
}
else
{
/* error handling */
}
str++;
}
return result
}
The digits in the C string are ASCII representation of the character representing the letter or digit. '0' is not represented in the char array by zero but 0x30.
Change your getvalue to
unsigned int getvalue(const char *data, int offset)
{
unsigned int payload = 0;
for (unsigned char i = 0; i < 8; i++)
{
payload <<= 4;
if (data[i + offset] >= 'a') {
payload |= (data[i + offset] - 97) + 10;
} else if (data[i + offset] >= 'A') {
payload |= (data[i + offset] - 65) + 10;
} else {
payload |= (data[i + offset] - 48);
}
}
return payload;
}
Each hex value occupies 4 bits, hence << 4
Each char in the string is in its ASCII code, hence the subtraction.
ASCII value of 'a' is 97, but the decimal value must be 10, so the expression will be 'a' - 97 + 10
There is no need to reinvent the wheel. There is a library function to do this: strtol.
#include <stdlib.h>
unsigned int getvalue(const char *data, int offset)
{
char *end;
long payload = strtol(&data[offset],&end,16);
if (*end || payload < 0 || payload > UINT_MAX) {
/* error handling */
}
return (unsigned int)payload;
}
I've been trying to perform CRC16 MCRF4XX in my code however I've managed to do it correctly for only 1 byte.
I've followed this guide, for the specific method: http://www.piclist.com/techref/method/error/quickcrc16.htm
and i've tested the same byte in https://crccalc.com/
code is as follows:
register uint32_t i;
uint16_t Crc = 0;
for ( i = 0; i < Len; i++ )
Crc = Utils_CRC16_MCRF4XX(Crc,pData[i]);
return ( Crc );
the function "Utils_CRC16_MCRF4XX":
uint8_t i;
uint16_t TempByte, CurrentCRC = 0xFFFF;
//make byte 16 bit format
TempByte = (uint16_t)Byte;
for ( i = 0; i < 8; i++ )
{
if ( (CurrentCRC & 0x0001) == (TempByte & 0x0001) )
{
//right shift crc
CurrentCRC >>= 1;
//right shift data
TempByte >>= 1;
}
else
{
CurrentCRC >>= 1;
TempByte >>= 1;
CurrentCRC = CurrentCRC ^ 0x8408; /* 1000 0100 0000 1000 = x^16 + x^12 + x^5 + 1 */
}
}
return ( Crc ^ CurrentCRC);
the output for byte 0x54 would be 0x1B26.
I've tried XORing the output with the inserted Crc, but it doesn't add up right.
now my issue starts when I'm trying to feed the function more than 1 byte.
if let's say i would send it : 0x54 0xFF.
it would give me a totally different calculation than the calculator gives.
I'm assuming my error is where i add up the bytes together, after performing the action on each byte.
appreciate the help!
Your function Utils_CRC16_MCRF4XX should update the Crc, but keeps its own CurrentCRC variable that bares no relationship to the current CRC value and is reinitialised to 0xFFFF on each call. The Crc parameter passed in is teh current CRC and that should be updated.
Adapting your function with minimal changes:
uint16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
//make byte 16 bit format
uint16_t TempByte = (uint16_t)Byte;
for( uint8_t i = 0; i < 8; i++ )
{
if( (Crc & 0x0001) == (TempByte & 0x0001) )
{
//right shift crc
Crc >>= 1;
//right shift data
TempByte >>= 1;
}
else
{
Crc >>= 1;
TempByte >>= 1;
Crc = Crc ^ 0x8408;
}
}
return Crc ;
}
In the code that calls this, the Crc must be initialised to 0xFFFF, not zero:
uint16_t crc( uint8_t* pData, uint32_t Len )
{
uint16_t Crc = 0xffffu ;
for( uint32_t i = 0; i < Len; i++ )
{
Crc = Utils_CRC16_MCRF4XX( Crc, pData[i] );
}
return (Crc);
}
The following test code, produces the result 0x6F91 which concurs with https://crccalc.com/:
int main()
{
uint8_t test[] = "123456789" ;
uint16_t c = crc( test, sizeof(test) - 1 ) ;
printf( "%X", (int)c ) ;
return 0 ;
}
The implicit conversion that occurs when applying the & operator make TempByte redundant so further simplification is possible:
uint16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
for( uint8_t i = 0; i < 8; i++ )
{
if( (Crc & 0x0001) == (Byte & 0x0001) )
{
Crc >>= 1;
Byte >>= 1;
}
else
{
Crc >>= 1;
Byte >>= 1;
Crc = Crc ^ 0x8408;
}
}
return Crc ;
}
Adapting the solution at https://gist.github.com/aurelj/270bb8af82f65fa645c1 yields the somewhat more succinct solution:
uint16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
Crc ^= Byte ;
for( uint8_t i = 0; i < 8; i++ )
{
Crc = (Crc & 0x0001) != 0 ? (Crc >> 1) ^ 0x8408 :
Crc >> 1 ;
}
return Crc ;
}
Completed code, including main() driver.
#include <stdint.h>
#include <stdio.h>
uint16_t Utils_CRC16_MCRF4XX(uint16_t crc, uint16_t byte);
int main(int argc, char **argv) {
uint32_t i;
uint16_t crc ;
uint8_t data[200] = { 0 };
uint32_t len ;
for(len = 0; len+1 < argc; len++ ) {
sscanf(argv[len+1], "%hhx", &data[len] );
}
crc = 0xffff;
for ( i = 0; i < len; i++ ) {
crc = Utils_CRC16_MCRF4XX(crc, data[i] );
fprintf(stderr, "[%u] %2hhx CrC=%04x\n", (unsigned) i, data[i], (unsigned) crc);
}
fprintf(stderr, "CrC=%04x\n", (unsigned) crc);
return 0 ;
}
uint16_t Utils_CRC16_MCRF4XX(uint16_t crc, uint16_t byte)
{
uint8_t i;
for ( i = 0; i < 8; i++ ) {
register int samelow;
samelow = (crc & 1) == (byte & 1) ?1 : 0 ;
crc >>= 1;
byte >>= 1;
if (!samelow) crc ^= 0x8408; /* 1000 0100 0000 1000 = x^16 + x^12 + x^5 + 1 */
}
return crc;
}
I found this CRC32 implementation on the internet, little bit changed it, but I can't get it to work. I initialize it and update it on every byte I get from input, but the hash I get is not what it should be...
typedef struct {
unsigned short xor;
} xor_context;
void crc32_init(crc32_context *context) {
context->crc = 0xFFFFFFFF;
}
void crc32_update(crc32_context *context, unsigned char byte) {
uint32_t crc, mask;
crc = context->crc;
crc = crc ^ byte;
for (int j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
context->crc = ~crc;
}
This one is original
unsigned int crc32b(unsigned char *message) {
int i, j;
unsigned int byte, crc, mask;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
byte = message[i]; // Get next byte.
crc = crc ^ byte;
for (j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}
//typedef struct {
// unsigned short xor;
//} xor_context;//--> Not sure what part this plays in the code!
void crc32_init(crc32_context *context) {
context->crc = 0xFFFFFFFF;
}
void crc32_update(crc32_context *context, unsigned char byte) {
uint32_t crc, mask;
crc = context->crc;
crc = crc ^ byte;
for (int j = 7; j >= 0; j--) { // Do eight times.
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
//context->crc = ~crc; //<-- Don't perform for every byte.
context->crc = crc; //EDIT: Forgot this!
}
//Completes the check.
uint32_t crc32_complete(crc32_context *context){
return ~context->crc;
}
Usually bit operations are done in smaller data width such as int, unsigned int or wchar_t. Assuming we want to use the bit strings in a longer format, how to shift, get and set bits for bits in char string?
One way may be to divide and conquer using the conventional method, but how do we ensure the bit carry over?
Given
#define numberOfState 2000 // number of bits
#define numberOfBitsIn1Byte 8
char* record;
int numberOfCharRequiredToRepresentBits =
ceil(((float)numberOfState/(float)numberOfBitsIn1Byte));
record = (char*) malloc(sizeof(char)*numberOfCharRequiredToRepresentBits);
// record = "NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S";
// optional : initialization by doing the set bit according to
// input from files. After which, do free(record);
How may we conduct bit operations such as to
i. shift the *record
ii. get bits from a specific bit position in *record
iii. set bits from a specific bit position in *record
Please have a try with following code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int isLittleEndian = 1;
void checkEndian(void)
{
union
{
short inum;
char c[sizeof(short)];
} un;
un.inum=0x0102;
if(un.c[0]==1 && un.c[1]==2)
{
printf("big_endian.\n");
isLittleEndian = 0;
}
else if(un.c[0]==2 && un.c[1]==1)
{
printf("little_endian.\n");
isLittleEndian = 1;
}
}
void shift_L(char *src, char * dst, int len, int n)
{
int shiftBytes = n/8;
int shiftBits = n%8;
memset(dst, 0, len);
memcpy(dst, src + shiftBytes, len - shiftBytes);
if (shiftBits)
{
int i = 0;
unsigned short tmp = 0;
for ( i = 0; i < len; i++)
{
if (isLittleEndian)
{
tmp = *(dst+i) << 8 | *(dst+i+1);
tmp <<= shiftBits;
*(dst+i) = *((char *)&tmp + 1);
}
else
{
tmp = *(short *)(dst+i);
tmp <<= shiftBits;
*(dst+i) = *((char *)&tmp);
}
}
}
}
void shift_R(char *src, char * dst, int len, int n)
{
int shiftBytes = n/8;
int shiftBits = n%8;
memset(dst, 0, len);
memcpy(dst + shiftBytes, src, len - shiftBytes);
if (shiftBits)
{
int i = 0;
unsigned short tmp = 0;
for ( i = len -1; i >= 0; i--)
{
if (isLittleEndian)
{
tmp = *(dst+i-1) << 8 | *(dst+i);
tmp >>= shiftBits;
*(dst+i) = *((char *)&tmp);
}
else
{
tmp = *(short *)(dst+i-1);
tmp >>= shiftBits;
*(dst+i) = *((char *)&tmp+1);
}
}
}
}
int getBit(char *src, int n)
{
unsigned char tmp = *(src + n/8);
unsigned char mask = (0x1 << (8 - n%8 - 1));
int bit = 0;
bit = (tmp & mask) > 0;
printf("%d", bit);
}
void setBit(char *src, int n, int bit)
{
unsigned char * pTmp = src + n/8;
unsigned char mask = (0x1 << (8 - n%8 - 1));
if (bit)
{
*pTmp |= mask;
}
else
{
*pTmp &= ~mask;
}
}
void dumpBin(unsigned char *src, int len)
{
int i = 0;
int j = 0;
unsigned char mask = 0;
for ( i = 0; i < len; i++)
{
for ( j = 0; j < 8; j++)
{
mask = 0x1 << 8 - j - 1;
printf("%d",(*(src + i) & mask) > 0);
}
}
}
void main()
{
char *record = "NAXHDKAN552ajdasdadNDfadsEBEAfA8gda5214S";
//char *record = "NAXHDKA";
int recordLen = strlen(record);
char * buffer = NULL;
int i = 0;
checkEndian();
recordLen = recordLen + recordLen%2;
buffer = malloc(recordLen);
memcpy(buffer, record, recordLen);
printf("\n input bit stream:\n");
dumpBin(buffer, recordLen);
printf("\n bit stream from getBit:\n");
for ( i = 0; i < recordLen*8; i++)
{
getBit(buffer, i);
}
setBit(buffer, 8, 1);
setBit(buffer, 9, 0);
setBit(buffer, 10, 1);
setBit(buffer, 11, 1);
printf("\n bit stream after setBit:\n");
dumpBin(buffer, recordLen);
shift_L(record, buffer, recordLen, 1);
printf("\n bit stream after shift_L:\n");
dumpBin(buffer, recordLen);
shift_R(record, buffer, recordLen, 9);
printf("\n bit stream after shift_R:\n");
dumpBin(buffer, recordLen);
printf("\n");
free(buffer);
}
Your bitstream is essentially an array of char. So, to perform these operations you work on these char elements.
i. The shifting operation depends on the number of bits you want to shift.
If the number is a multiple of 8, it is pretty straightforward, you just copy the elements right of left as many bytes as the number is a multiple of 8.
If the number is less than 8, you perform the operation on every element of the array, but you need to or the overflowing bits of the previous element. For example, in left shift, element i must incorporate the overflowing bits of element i+1, and on right shift, the overflowing bits of element i-1.
Any other number of bits you want to shift can be achieved by a combination of these two actions. For example, a left shift by 18 is a shift by 16 followed by a shift by 2.
In any case, you need to be careful on which side of the bitstring you start, so that you do not lose data.
ii. In order to get the n-th bit of the bitstream, you access the element with index n/8 (integer division) and get the n%8 bit from it.
iii. Pretty much the same as ii.
I would like to store 4 char (4 bytes) into an unsigned int.
You need to shift the bits of each char over, then OR combine them into the int:
unsigned int final = 0;
final |= ( data[0] << 24 );
final |= ( data[1] << 16 );
final |= ( data[2] << 8 );
final |= ( data[3] );
That uses an array of chars, but it's the same principle no matter how the data is coming in. (I think I got the shifts right)
One more way to do this :
#include <stdio.h>
union int_chars {
int a;
char b[4];
};
int main (int argc, char const* argv[])
{
union int_chars c;
c.a = 10;
c.b[0] = 1;
c.b[1] = 2;
c.b[2] = 3;
c.b[3] = 4;
return 0;
}
More simple, its better :
/*
** Made by CHEVALLIER Bastien
** Prep'ETNA Promo 2019
*/
#include <stdio.h>
int main()
{
int i;
int x;
char e = 'E';
char t = 'T';
char n = 'N';
char a = 'A';
((char *)&x)[0] = e;
((char *)&x)[1] = t;
((char *)&x)[2] = n;
((char *)&x)[3] = a;
for (i = 0; i < 4; i++)
printf("%c\n", ((char *)&x)[i]);
return 0;
}
You could do it like this (not bit-wise, but maybe more easy):
unsigned int a;
char *c;
c = (char *)&a;
c[0] = 'w';
c[1] = 'o';
c[2] = 'r';
c[3] = 'd';
Or if you want bit-wise you can use:
unsigned int a;
a &= ~(0xff << 24); // blank it
a |= ('w' << 24); // set it
// repeat with 16, 8, 0
If you don't blank it first you might get another result.