I am wondering if anyone can help me. I am new to c and only learning. So this questain may seem confused. I have an unsigned int value that I need to split into bytes then xor certain bytes together and then get the result. I want represent the value as (0, a0 ⊕ a1,a2 ⊕a3,0).
Decimal value = 62910759 or Hex value = 3BFF127;
unsigned int value = 62910759;
// W = (0, a0 ⊕ a1,a2 ⊕a3,0);
unsigned int L = 0x04000000L^ W ;
I don't know if this helps you, but i calculate the bytes first and then XOR some of them:
unsigned int value = 62910759;
unsigned char a = value >> 24 & 0xFF; // First byte/ high byte
unsigned char b = value >> 16 & 0xFF;
unsigned char c = value >> 8 & 0xFF;
unsigned char d = value & 0xFF; // Last byte/ smallest byte
printf("%.2X %.2X %.2X %.2X\n", a,b,c,d);
unsigned char aXORb = a^b; // a XOR b
unsigned char bXORc = b^c;
unsigned char cXORd = c^d;
unsigned char dXORa = d^a;
printf("%.2X %.2X %.2X %.2X\n", aXORb,bXORc,cXORd,dXORa);
Try it here.
Output:
03 BF F1 27
BC 4E D6 24
Note: I think uint8_t would be more "C-like" but the result will be the same anyway.
#Jimbo Jones Here is the last step. The zeros are unnecessary, but i included them for better understanding the code.
unsigned int result = (0x00 << 24) + (aXORb << 16) + (cXORd << 8) + 0x00;
Method(0x02000000L^ result);
If you mean with W = (0, a0 ⊕ a1,a2 ⊕a3,0) that the first 8 bit are 0 and the next 8 a XOR b and so on.
Related
for example i have uint64_t value = 42 and i would like to split it into 8 uint8_t (8 bits), little endian. But I am unsure how to do the bit shifting. Help would be much appreciated.
If you want the individual bytes of a 64-bit value in little endian, then you can do the following:
In order to get the 1st byte, you simply apply the AND-bitmask 0xFF. This will mask out all bits except for the 8 least-significant bits.
In order to get the 2nd byte, you shift right by 8 bits before applying the bit-mask.
In order to get the 3rd byte, you shift right by 16 bits before applying the bit-mask.
In order to get the 4th byte, you shift right by 24 bits before applying the bit-mask.
(...)
In order to get the 8th byte, you shift right by 56 bits before applying the bit-mask.
Here is the code for the value 42 (which is the example in the question):
#include <stdio.h>
#include <stdint.h>
int main( void )
{
uint64_t value = 42;
uint8_t bytes[8];
//extract the individual bytes
for ( int i = 0; i < 8; i++ )
{
bytes[i] = value >> (8 * i) & 0xFF;
}
//print the individual bytes
for ( int i = 0; i < 8; i++ )
{
printf( "%2d ", bytes[i] );
}
printf( "\n" );
}
Output:
42 0 0 0 0 0 0 0
If you replace the value 42 with the value 74579834759 in the program above, then you get the following output:
135 247 77 93 17 0 0 0
The following code works on both little-endian and big-endian platforms. On both types of platforms, it will produce the bytes in little-endian byte order.
uint64_t input = 42;
uint8_t values[8];
values[0] = input >> 0 & 0xFF;
values[1] = input >> 8 & 0xFF;
values[2] = input >> 16 & 0xFF;
values[3] = input >> 24 & 0xFF;
values[4] = input >> 32 & 0xFF;
values[5] = input >> 40 & 0xFF;
values[6] = input >> 48 & 0xFF;
values[7] = input >> 56 & 0xFF;
Note that the & 0xFF is redundant here, but it makes the code more clear and it's useful if you want to do anything with the value other than immediately assign it to a uint8_t variable.
Macro extracts bth byte form the u integer
#define EXTRACT(u,b) ((u) >> (8 * (b)))
int foo(uint64_t x)
{
uint8_t b[8] = {
EXTRACT(x,0),
EXTRACT(x,1),
EXTRACT(x,2),
EXTRACT(x,3),
EXTRACT(x,4),
EXTRACT(x,5),
EXTRACT(x,6),
EXTRACT(x,7),
};
}
If the platform is little endian you can also use memcpy
void foo(uint64_t x)
{
uint8_t b[8];
memcpy(b, &x, sizeof(b));
}
Here's a pointer approach to retrieve byte data from u64 data I usually use. Just share with you. But in this way, the user has to take care of the order.
#include <stdio.h>
#include <stdint.h>
void main(void)
{
int i;
uint64_t v = 0x123456789abcdef0;
uint8_t* ptrb;
ptrb = (uint8_t*)&v;
for (i = 0; i < 8; i++)
{
printf("%2x ", ptrb[i]);
}
printf("\n");
}
Below is the output with my sample code,
$ ./foo
f0 de bc 9a 78 56 34 12
I have a byte array represented as
char * bytes = getbytes(object); //some api function
I want to check whether the bit at some position x is set.
I've been trying this
int mask = 1 << x % 8;
y= bytes[x>>3] & mask;
However y returns as all zeros? What am I doing incorrectly and is there an easier way to check if a bit is set?
EDIT:
I did run this as well. It didn't return with the expected result either.
int k = x >> 3;
int mask = x % 8;
unsigned char byte = bytes[k];
return (byte & mask);
it failed an assert true ctest I ran. Byte and Mask at this time where "0002" and 2 respectively when printed from gdb.
edit 2: This is how I set the bits in the first place. I'm just trying to write a test to verify they are set.
unsigned long x = somehash(void* a);
unsigned int mask = 1 << (x % 8);
unsigned int location = x >> 3;
char* filter = getData(ref);
filter[location] |= mask;
This would be one (crude perhaps) way from the top of my head:
#include "stdio.h"
#include "stdlib.h"
// this function *changes* the byte array
int getBit(char *b, int bit)
{
int bitToCheck = bit % 8;
b = b + (bitToCheck ? (bit / 8) : (bit / 8 - 1));
if (bitToCheck)
*b = (*b) >> (8 - bitToCheck);
return (*b) & 1;
}
int main(void)
{
char *bytes = calloc(2, 1);
*(bytes + 1)= 5; // writing to the appropiate bits
printf("%d\n", getBit(bytes, 16)); // checking the 16th bit from the left
return 0;
}
Assumptions:
A byte is represented as:
----------------------------------------
| 2^7 | 2^6 | 2^5 | 2^4 | 2^3 |... |
----------------------------------------
The left most bit is considered bit number 1 and the right most bit is considered the max. numbered bit (16th bit in a 2 byte object).
It's OK to overwrite the actual byte object (if this is not wanted, use memcpy).
i have a 32 bit instruction that i wish to split into four bytes.
Let say the instruction looks like this:
yyyyyzzzzzzxxxxxx?????????
The instruction is a word that consists of four unsigned ints. y represents the operation code, and ??? are for the unused space. I am working on a big-endian machine.
What I would like to happen is to move the values from z + w to a.
I have never worked in C before but I have tried to do it like this.
Here is how I read the word, just so I ca print out each byte:
unsigned int a, b, c, o;
w = instruction << 24;
z = instruction << 16;
x = instruction << 8;
y = instruction;
Here I print unsigned values, just to check what the result are.
printf("%u\n", w);
printf("%u\n", z);
printf("%u\n", x);
printf("%u\n", y);
printf("\n");
regs[x] = instruction + instruction << 8;
if I print out the values of regs[x] after this, then I can see that I has a value now, but is this the correct way of doing it? When I do like this, do I set the register = z + w?
EDIT
Mabye i should get the bits like this?
y = (inst >> 24) & 077;
x = (inst >> 16) & 0xffff;
z = (inst >> 8) & 0xffff;
w = (inst) & 0xffff;
and then do like this:
regs[y] = z + w;
If you like to use only bit positions and counts you can build a bit mask of i.e. 9 bits with setting the next bit and decrement (1<<10)-1. So your values are
#define MASK(n) ((1<<(n+1))-1)
unsigned int w = instruction & MASK(9);
unsigned int x = (instruction >> 9) & MASK(6);
unsigned int z = (instruction >> 15) & MASK(6);
unsigned int y = (instruction >> 21) & MASK(5);
all values are down shifted. So if you like to combine z and w you will have to
unsigned int zw = z<<9 | w;
because w contains 9 bits, or
unsigned int wz = w<<6 | z;
because z contains 6 bits.
Suppose you have an integer a = 0x12345678 & a short b = 0xabcd
What i wanna do is replace the given nibbles in integer a with nibbles from short b
Eg: Replace 0,2,5,7th nibbles in a = 0x12345678 (where 8 = 0th nibble, 7=1st nibble, 6=2nd nibble and so on...) with nibbles from b = 0xabcd (where d = 0th nibble, c=1st nibble, b=2nd nibble & so on...)
My approach is -
Clear the bits we're going to replace from a.
like a = 0x02045070
Create the mask from the short b like mask = 0xa0b00c0d
bitwise OR them to get the result. result = a| mask i.e result = 0xa2b45c7d hence nibbles replaced.
My problem is I don't know any efficient way to create the desired mask (like in step 2) from the given short b
If you can give me an efficient way of doing so, it would be a great help to me and I thank you for that in advance ;)
Please ask if more info needed.
EDIT:
My code to solve the problem (not good enough though)
Any improvement is highly appreciated.
int index[4] = {0,1,5,7}; // Given nibbles to be replaced in integer
int s = 0x01024300; // integer mask i.e. cleared nibbles
int r = 0x0000abcd; // short (converted to int )
r = ((r & 0x0000000f) << 4*(index[0]-0)) |
((r & 0x000000f0) << 4*(index[1]-1)) |
((r & 0x00000f00) << 4*(index[2]-2)) |
((r & 0x0000f000) << 4*(index[3]-3));
s = s|r;
Nibble has 4 bits, and according to your indexing scheme, the zeroth nibble is represented by least significant bits at positions 0-3, the first nibble is represented by least significant bits at positions 4-7, and so on.
Simply shift the values the necessary amount. This will set the nibble at position set by the variable index:
size_t index = 5; //6th nibble is at index 5
size_t shift = 4 * index; //6th nibble is represented by bits 20-23
unsigned long nibble = 0xC;
unsigned long result = 0x12345678;
result = result & ~( 0xFu << shift ); //clear the 6th nibble
result = result | ( nibble << shift ); //set the 6th nibble
If you want to set more than one value, put this code in a loop. The variable index should be changed to an array of values, and variable nibble could also be an array of values, or it could contain more than one nibble, in which case you extract them one by one by shifting values to the right.
A lot depends on how your flexible you are in accepting the "nibble list" index[4] in your case.
You mentioned that you can replace anywhere from 0 to 8 nibbles. If you take your nibble bits as an 8-bit bitmap, rather than as a list, you can use the bitmap as a lookup in a 256-entry table, which maps from bitmap to a (fixed) mask with 1s in the nibble positions. For example, for the nibble list {1, 3}, you'd have the bitmap 0b00001010 which would map to the mask 0x0000F0F0.
Then you can use pdep which has intrinsics on gcc, clang, icc and MSVC on x86 to expand the bits in your short to the right position. E.g., for b == 0xab you'd have _pdep_u32(b, mask) == 0x0000a0b0.
If you aren't on a platform with pdep, you can accomplish the same thing with multiplication.
To be able to change easy the nibbles assignment, a bit-field union structure could be used:
Step 1 - create a union allowing to have nibbles access
typedef union u_nibble {
uint32_t dwValue;
uint16_t wValue;
struct sNibble {
uint32_t nib0: 4;
uint32_t nib1: 4;
uint32_t nib2: 4;
uint32_t nib3: 4;
uint32_t nib4: 4;
uint32_t nib5: 4;
uint32_t nib6: 4;
uint32_t nib7: 4;
} uNibble;
} NIBBLE;
Step 2 - assign two NIBBLE items with your integer a and short b
NIBBLE myNibbles[2];
uint32_t a = 0x12345678;
uint16_t b = 0xabcd;
myNibbles[0].dwValue = a;
myNibbles[1].wValue = b;
Step 3 - initialize nibbles of a by nibbles of b
printf("a = %08x\n",myNibbles[0].dwValue);
myNibbles[0].uNibble.nib0 = myNibbles[1].uNibble.nib0;
myNibbles[0].uNibble.nib2 = myNibbles[1].uNibble.nib1;
myNibbles[0].uNibble.nib5 = myNibbles[1].uNibble.nib2;
myNibbles[0].uNibble.nib7 = myNibbles[1].uNibble.nib3;
printf("a = %08x\n",myNibbles[0].dwValue);
Output will be:
a = 12345678
a = a2b45c7d
If I understand your goal, the fun you are having comes from the reversal of the order of your fill from the upper half to the lower half of your final number. (instead of 0, 2, 4, 6, you want 0, 2, 5, 7) It isn't any more difficult, but it does make you count where the holes are in the final number. If I understood, then you could mask with 0x0f0ff0f0 and then fill in the zeros with shifts of 16, 12, 4 and 0. For example:
#include <stdio.h>
int main (void) {
unsigned a = 0x12345678, c = 0, mask = 0x0f0ff0f0;
unsigned short b = 0xabcd;
/* mask a, fill in the holes with the bits from b */
c = (a & mask) | (((unsigned)b & 0xf000) << 16);
c |= (((unsigned)b & 0x0f00) << 12);
c |= (((unsigned)b & 0x00f0) << 4);
c |= (unsigned)b & 0x000f;
printf (" a : 0x%08x\n b : 0x%0hx\n c : 0x%08x\n", a, b, c);
return 0;
}
Example Use/Output
$ ./bin/bit_swap_nibble
a : 0x12345678
b : 0xabcd
c : 0xa2b45c7d
Let me know if I misunderstood, I'm happy to help further.
With nibble = 4 bits and unsigned int = 32 bits, a nibble inside a unsigned int can be found as follows:
x = 0x00a0b000, find 3rd nibble in x i.e locate 'b'. Note nibble index starts with 0.
Now 3rd nibble is from 12th bit to 15th bit.
3rd_nibble can be selected with n = 2^16 - 2^12. So, in n all the bits in 3rd nibble will be 1 and all the bits in other nibbles will be 0. That is, n=0x00001000
In general, suppose if you want to find a continuous sequence of 1 in binary representation in which sequence starts from Xth bit to Yth bit then formula is 2^(Y+1) - 2^X.
#include <stdio.h>
#define BUF_SIZE 33
char *int2bin(int a, char *buffer, int buf_size)
{
int i;
buffer[BUF_SIZE - 1] = '\0';
buffer += (buf_size - 1);
for(i = 31; i >= 0; i--)
{
*buffer-- = (a & 1) + '0';
a >>= 1;
}
return buffer;
}
int main()
{
unsigned int a = 0;
unsigned int b = 65535;
unsigned int b_nibble;
unsigned int b_at_a;
unsigned int a_nibble_clear;
char replace_with[8];
unsigned int ai;
char buffer[BUF_SIZE];
memset(replace_with, -1, sizeof(replace_with));
replace_with[0] = 0; //replace 0th nibble of a with 0th nibble of b
replace_with[2] = 1; //replace 2nd nibble of a with 1st nibble of b
replace_with[5] = 2; //replace 5th nibble of a with 2nd nibble of b
replace_with[7] = 3; //replace 7th nibble of a with 3rd nibble of b
int2bin(a, buffer, BUF_SIZE - 1);
printf("a = %s, %08x\n", buffer, a);
int2bin(b, buffer, BUF_SIZE - 1);
printf("b = %s, %08x\n", buffer, b);
for(ai = 0; ai < 8; ++ai)
{
if(replace_with[ai] != -1)
{
b_nibble = (b & (1LL << ((replace_with[ai] + 1)*4)) - (1LL << (replace_with[ai]*4))) >> (replace_with[ai]*4);
b_at_a = b_nibble << (ai * 4);
a_nibble_clear = (a & ~(a & (1LL << ((ai + 1) * 4)) - (1LL << (ai * 4))));
a = a_nibble_clear | b_at_a;
}
}
int2bin(a, buffer, BUF_SIZE - 1);
printf("a = %s, %08x\n", buffer, a);
return 0;
}
Output:
a = 00000000000000000000000000000000, 00000000
b = 00000000000000001111111111111111, 0000ffff
a = 11110000111100000000111100001111, f0f00f0f
static unsigned int read24(unsigned char *ptr)
{
unsigned int b0;
unsigned int b1;
unsigned int b2;
unsigned int b3;
b0 = *ptr++;
b1 = *ptr++;
b2 = *ptr++;
b3 = *ptr;
return ( ((b0 >> 24) & 0x000000ff) |
((b1 >> 8) & 0x0000ff00) |
((b2 << 8) & 0x00ff0000) |
(b3 << 24) & 0x00000000 // this byte is not important so make it zero
);
}
Here i have written a function and am trying to read 32 bits (4bytes) using a char pointer and return those 32 bits (4bytes).I have a doubt if this will work properly.Also,am i using/wasting too much memory by defining 4 different integer variables?Is there a better way to write this function. Thank you for your time.
First, drop b3, since you're apparently meaning to read 24 bits you shouldn't even try to access that extra byte (what if it's not even allocated?).
Second, I think you have your shifts wrong. b0 will always be in the range [0..255], so if you >> 24, it'll become zero. There's also no need to mask anything out, since you're coming from unsigned char you know you'll only have 8 bits set. You probably want either:
return (b0 << 16) | (b1 << 8) | b2;
or
return (b2 << 16) | (b1 << 8) | b0;
depending on the endianness of your data.
As for using those intermediate ints, if you have a decent compiler it won't matter (the compiler will optimize them out). If however you're writing for an embedded platform or otherwise have a less-than state of the are compiler, it's possible that eliding the intermediate ints may help your performance. In this case, don't put multiple ptr++s in the same statement, use ptr[n] instead to avoid undefined behavior from multiple increments.
Well, I'm not too clear on what you're attempting to do. If I'm not mistaken you want to input a char* (Most likely 4 bytes if you're running a 32 bit system) and get the same organization of bytes as an int* (4 bytes)
If all you want is the int* version of a char* set of bytes you can use type-casting:
unsigned int* result = (unsigned int*)ptr;
If you want the same collection of bytes BUT you want the most significant byte to be equal to 0 then you can do this:
unsigned int* result = (unsigned int*)ptr & 0x0FFF;
Some additional info:
-Type Casting is a method of temporarily "casting" a variable as any type you want via the use of a temporary copy that is of the type your casting the variable to You can make a variable act as any type you want if you typecast it:
Example:
unsigned int varX = 48;
//Prints "Ascii decimal value 48 corresponds with: 0"
printf ("Ascii decimal value 48 corresponds with: %c\n", (char)varX);
-Hexidicamal digits occupy one byte each. So in your code:
0x000000ff -> 8 bytes of data
0x implies that each of the place holders are a hexidecimal value and
I think what you were going for was 0x000F, which would make all the other bytes 0 except the least significant byte
ANSI-C can process hexidecimal(prefix -> 0x), octal(prefix -> 0) and decimal
Hope this helped!
When building your number from the individual pointers, you must shift the numbers to the left as you incrementally Or the values together. (for little endian machines). Think of it this way, after you read b0, that will be the least significant byte in your final number. Where do more significant bytes go? (to the left).
When you read a pointer value into b0, b1, b2, b3, all they hold is one byte each. They have no way of knowing where they came from in the original number, so there is no "relative" shifting required. You just start with the least significant byte, and incrementally shift each successive byte to the left by 1 byte more than the last.
Below, I have used all bytes in the building of the unsigned value from the unsigned char pointers as an example. You can simply omit bytes you do not need to meet your needs.
#include <stdio.h>
#include <stdlib.h>
#if defined(__LP64__) || defined(_LP64)
# define BUILD_64 1
#endif
#ifdef BUILD_64
# define BITS_PER_LONG 64
#else
# define BITS_PER_LONG 32
#endif
char *binstr (unsigned long n);
static unsigned int read24 (unsigned char *ptr);
int main (void) {
unsigned int n = 16975631;
unsigned int o = 0;
o = read24 ((unsigned char *)&n);
printf ("\n number : %u %s\n", n, binstr (n));
printf (" read24 : %u %s\n\n", o, binstr (o));
return 0;
}
static unsigned int read24 (unsigned char *ptr)
{
unsigned char b0;
unsigned char b1;
unsigned char b2;
unsigned char b3;
b0 = *ptr++; /* 00001111000001110000001100000001 */
b1 = *ptr++; /* b0 b1 b2 b3 */
b2 = *ptr++; /* b3 b2 b1 b0 */
b3 = *ptr; /* 00000001000000110000011100001111 */
return ((b0 & 0x000000ffU) |
((b1 << 8 ) & 0x0000ff00U) |
((b2 << 16) & 0x00ff0000U) |
((b3 << 24) & 0xff000000U));
}
/* simple return of binary string */
char *binstr (unsigned long n)
{
static char s[BITS_PER_LONG + 1] = {0};
char *p = s + BITS_PER_LONG;
if (!n) {
*s = '0';
return s;
}
while (n) {
*(--p) = (n & 1) ? '1' : '0';
n >>= 1;
}
return p;
}
Output
$ ./bin/rd_int_as_uc
number : 16975631 1000000110000011100001111
read24 : 16975631 1000000110000011100001111
Consider using the following approach for your task:
#include <string.h>
unsigned int read24b(unsigned char *ptr)
{
unsigned int data = 0;
memcpy(&data, ptr, 3);
return data;
}
This is for case if you want direct order of bits, but I suppose you do not...
Concerning your code - you must apply mask and then make shift, e.g.:
unsigned int read24(unsigned char *ptr)
{
unsigned char b0;
unsigned char b1;
unsigned char b2;
b0 = *ptr++;
b1 = *ptr++;
b2 = *ptr;
return ( (b0 & 0x0ff) >> 16 |
(b1 & 0x0ff) >> 8 |
(b2 & 0x0ff)
);
}