I want to convert an array of uint8_t to a uint32_t in NesC.
Does anyone know how I can do this?
The solution that i were found is the use of the function :
void * memcpy ( void * destination, const void * source, size_t num );
There is also the function :
void * memset ( void * ptr, int value, size_t num );
In my code i use memcpy and it works fine. Thanks to all people that answer my question
If you want to convert a single uint8_t in the source to a single uint32_t in the destination, it's actually very simple. Just create the destination array, and copy the values in a loop:
uint8_t *source;
size_t source_count; /* Number of entries in the source */
uint32_t *dest = malloc(sizeof(*dest) * source_count);
for (int i = 0; i < source_count; i++)
dest[i] = source[i];
Your title mentions strings, but your question text doesn't. This is confusing.
If you have four 8-bit integers, you can join them into a single 32-bit like so:
const uint8_t a = 1, b = 2, c = 3, d = 4;
const uint32_t big = (a << 24) | (b << 16) | (c << 8) | d;
This orders them like so, where letters denote bits from the variables above:
0xaabbccdd
In other words, a is taken to be the most significant byte, and d the least.
If you have an array, you can of course do this in a loop:
uint32_t bytes_to_word(const uint8_t *bytes)
{
size_t i;
uint32_t out = 0;
for(i = 0; i < 4; ++i)
{
out <<= 8;
out |= bytes[i];
}
return out;
}
The above assumes that bytes has four values.
Related
I'm not sure how to put what I am trying to achieve in words, but I'll just put an example below, hope you guys can lend me a hand!
Basically I'm trying to copy the hex representation of uint64_t value into an unsigned char array, in hex.
What I have:
uint64_t src;
unsigned char destination[8];
/* codes omitted, some codes that will change the value of src */
printf("src: %"PRIx64"\n", src); //this prints out src: 3132333435363738
How do I copy the values from src into destination array in a way that:
destination[0] = 0x31;
destination[1] = 0x32;
destination[2] = 0x33;
//and so on...
Thanks!
EDIT
I'm sorry If my question is unclear, I'm very new to programming and I'm struggling to explain myself.
Basically I'm just trying to store whatever that prints out from that printf() into the unsigned char array as hex.
e.g, printf() outputs a string of "3132333435363738", I want to take 31 and store it in dst[0] where the value of dst[0] will be 0x31, and so on, where dst[1] will be 0x32.
Please bear with me, thanks!
The easy and portable way to extract the bytes that make up an integer in a given order is to just use bit shifts (and possibly masks); in your case, you seem to want to extract your bytes in big-endian order (first byte in destination => most significant byte in src), so that would be:
uint64_t src;
unsigned char destination[8];
for(int i=0; i<8; ++i) {
destination[i] = src>>((7-i)*8);
}
At each iteration, src is shifted to the right by (7-i)*8 bits, because we want the desired byte to go "at the bottom" of the result
First iteration:
src = 0x123456789abcdef0;
i = 0
(7-i) = 7
src >> ((7-i)*8) = 0x12
so, we got 0x12 and we put it into destination[0]; at the next iteration, we have
i = 1
(7-i) = 6
src >> ((7-i)*8) = 0x1234
Now, we could mask the result with 0xFF to take only the bottom 8 bit (namely, 0x34), but that's not important in our case, since each element of destination is an unsigned byte, so when assigning a value larger than 255 (as in this case) it does unsigned overflow, which is well defined to take only the lower bytes that "fit" the target; so, destination[1]=0x34.
Repeat this for i up to 7 and you get the required result.
You can set a pointer to point to the uint64_t itself:
uint64_t src;
unsigned char *view;
view = (unsigned char *)&src;
for (size_t i = 0; i < sizeof(src); ++i) {
printf("%x", view[i]);
}
printf("\n");
If you need to copy the value, not just have another view of it, the same principle applies:
uint64_t src;
unsigned char dst[sizeof(src)];
memcpy((void *)&dst, (void *)&src, sizeof(src));
for (size_t i = 0; i < sizeof(src); ++i) {
printf("%x", dst[i]);
}
printf("\n");
Note that this will inherit the native endianness of the platform. If you want to convert endianness, you can use the library function uint64_t htobe64(uint64_t x) (Linux,BSD) or OSSwapHostToBigInt64(x) (OS X) on src before viewing/copying the string. I don't know the equivalents for Windows but I assume they have them. See I used unsigned char instead of char to avoid any sign extension issues.
Solutions using pointer casts + pointer arithmetic, or solutions using unions will not be portable.
Here is a simple way to do this portably, no matter endianess. There may be more effective ways.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdbool.h>
int main(void)
{
uint64_t src;
uint8_t destination[8] = {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38};
const uint16_t dummy = 1;
const bool is_little_endian = *(const uint8_t*)&dummy == 1;
src=0;
for(size_t i=0; i<8; i++)
{
size_t shift = i*8;
if(is_little_endian)
{
shift = 64-8-shift;
}
src |= (uint64_t)destination[i] << shift;
}
printf("%" PRIx64, src);
return 0;
}
This is essentially the same as the solution given by #Matteo Italia, but using a mask and an explicit cast to the fixed width type uint8_t instead of unsigned char. These solutions should work regardless of endianness, because the bitwise operators work on the value of the left operand, not its underlying representation.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
uint64_t src = 0x3132333435363738;
uint8_t destination[8];
uint64_t mask = 0xff << 56;
size_t i;
for (i = 0; i < 8; i++) {
destination[i] = (uint8_t) ((src & mask) >> (56 - i * 8));
mask >>= 8;
}
printf("src: 0x%" PRIx64 "\n", src);
for (i = 0; i < 8; i++) {
printf("destination[%zu] = 0x%" PRIx8 "\n", i, destination[i]);
}
return 0;
}
Output is:
src: 0x3132333435363738
destination[0] = 0x31
destination[1] = 0x32
destination[2] = 0x33
destination[3] = 0x34
destination[4] = 0x35
destination[5] = 0x36
destination[6] = 0x37
destination[7] = 0x38
For my cuda project I want to give my device function a single integer.
My function looks like
__device__ void PBKDF2_CUDA(const uint8_t password[], const int pass_len, const uint8_t Essid[], const int Essid_len, const int c, const int dkLen, uint32_t T_ptr[], int *PW_len_test)
{
uint32_t Hash_ptr[5] = {0};
uint32_t L[5]={0,0,0,0,0};
uint32_t T[8] = {0};
//Maybe working
/*uint8_t * password_shrinked = (uint8_t*)malloc(8 + 1);
for(int i = 0; i < 8; i++)
password_shrinked[i] = password[i];
password_shrinked[8 + 1] = 0;*/
int password_len = pass_len;
if (pass_len != 8)
{
*PW_len_test = pass_len;
password_len = 8;
}
uint8_t * password_shrinked = (uint8_t*)malloc(sizeof(uint8_t)*(password_len + 1));
for (int i = 0; i < password_len; i++)
password_shrinked[i] = password[i];
password_shrinked[password_len + 1] = 0;
//Some other stuff
free(password_shrinked);
};
and I'm calling it from a kernel like this:
__global__ void kernel(uint8_t Password_list[], const int *Password_len, uint8_t Essid[], int *Essid_len, int *rounds,int *dkLen, uint32_t T[], int pmk_size, int *PW_len_test)
{
int idx= threadIdx.x + blockDim.x*blockIdx.x;
printf("Password_len is: %d\n", Password_len);
PBKDF2_CUDA(Password_list+idx*(8), 8, Essid, *Essid_len, *rounds, *dkLen, T+idx*pmk_size, PW_len_test + idx*sizeof(int));
}
Calling kernel in main function:
kernel<<<BLOCKS, THREADS>>>(Pass_d, Pass_len_d, Essid_d, Essid_len_d, rounds_d, key_len_d, PMK_d, PMK_size, PW_len_test_d);
Now, regardless if I set Pass_len_d to 8, or if I'm calling the kernel with 8 instead of Pass_len_d, my device function creates garbage (returning wrong values, explanation below). It only works if I set the value manually in the kernel function (as seen above) or in the device function.
With garbage I mean that some returned values are not calculated correctly from the password list (uint8_t array), but others are correctly calculated. Which words are correctly calculated changes with every run, so I assume there is a race condition somewhere, but I can not find it.
There's at least one buffer overflow.
password_shrinked[password_len + 1] = 0; writes to a slot one byte above what was allocated.
Remember that if you allocate password_len + 1 bytes, the last location in the array is password_len.
I am doing a GHASH for the AES-GCM implementation.
and i need to implement this
where v is the bit length of the final block of A, u is the bit length of the final block of C, and || denotes concatenation of bit strings.
How can I do the concatenation of A block to fill in the zeros padding from v to 128 bit, as I do not know the length of the whole block of A.
So I just take the A block and XOR it with an array of 128 bits
void GHASH(uint8_t H[16], uint8_t len_A, uint8_t A_i[len_A], uint8_t len_C,
uint8_t C_i[len_C], uint8_t X_i[16]) {
uint8_t m;
uint8_t n;
uint8_t i;
uint8_t j;
uint8_t zeros[16] = {0};
if (i == m + n) {
for(j=16; j>=0; j--){
C_i[j] = C_i[j] ^ zeros[j]; //XOR with zero array to fill in 0 of length 128-u
tmp[j] = X_i[j] ^ C_i[j]; // X[m+n+1] XOR C[i] left shift by (128bit-u) and store into tmp
gmul(tmp, H, X_i); //Do Multiplication of tmp to H and store into X
}
}
I am pretty sure that I am not correct. But I have no idea how to do it.
It seems to me that you've got several issues here, and conflating them is a big part of the problem. It'll be much easier when you separate them.
First: passing in a parameter of the form uint8_t len_A, uint8_t A_i[len_A] is not proper syntax and won't give you what you want. You're actually getting uint8_t len_A, uint8_t * A_i, and the length of A_i is determined by how it was declared on the level above, not how you tried to pass it in. (Note that uint8_t * A and uint8_t A[] are functionally identical here; the difference is mostly syntactic sugar for the programmer.)
On the level above, since I don't know if it was declared by malloc() or on the stack, I'm not going to get fancy with memory management issues. I'm going to use local storage for my suggestion.
Unit clarity: You've got a bad case going on here: bit vs. byte vs. block length. Without knowing the core algorithm, it appears to me that the undeclared m & n are block lengths of A & C; i.e., A is m blocks long, and C is n blocks long, and in both cases the last block is not required to be full length. You're passing in len_A & len_C without telling us (or using them in code so we can see) whether they're the bit length u/v, the byte length of A_i/C_i, or the total length of A/C, in bits or bytes or blocks. Based on the (incorrect) declaration, I'm assuming they're the length of A_i/C_i in bytes, but it's not obvious... nor is it the obvious thing to pass. By the name, I would have guessed it to be the length of A/C in bits. Hint: if your units are in the names, it becomes obvious when you try to add bitLenA to byteLenB.
Iteration control: You appear to be passing in 16-byte blocks for the i'th iteration, but not passing in i. Either pass in i, or pass in the full A & C instead of A_i & C_i. You're also using m & n without setting them or passing them in; the same issue applied. I'll just pretend they're all correct at the moment of use and let you fix that.
Finally, I don't understand the summation notation for the i=m+n+1 case, in particular how len(A) & len(C) are treated, but you're not asking about that case so I'll ignore it.
Given all that, let's look at your function:
void GHASH(uint8_t H[], uint8_t len_A, uint8_t A_i[], uint8_t len_C, uint8_t C_i[], uint8_t X_i[]) {
uint8_t tmpAC[16] = {0};
uint8_t tmp[16];
uint8_t * pAC = tmpAC;
if (i == 0) { // Initialization case
for (j=0; j<len_A; ++j) {
X_i[j] = 0;
}
return;
} else if (i < m) { // Use the input memory for A
pAC = A_i;
} else if (i == m) { // Use temp memory init'ed to 0; copy in A as far as it goes
for (j=0; j<len_A; ++j) {
pAC[j] = A_i[j];
}
} else if (i < m+n) { // Use the input memory for C
pAC = C_i;
} else if (i == m+n) { // Use temp memory init'ed to 0; copy in C as far as it goes
for (j=0; j<len_A; ++j) {
pAC[j] = C_i[j];
}
} else if (i == m+n+1) { // Do something unclear to me. Maybe this?
// Use temp memory init'ed to 0; copy in len(A) & len(C)
pAC[0] = len_A; // in blocks? bits? bytes?
pAC[1] = len_C; // in blocks? bits? bytes?
}
for(j=16; j>=0; j--){
tmp[j] = X_i[j] ^ pAC[j]; // X[m+n+1] XOR A or C[i] and store into tmp
gmul(tmp, H, X_i); //Do Multiplication of tmp to H and store into X
}
}
We only copy memory in the last block of A or C, and use local memory for the copy. Most blocks are handled with a single pointer copy to point to the correct bit of input memory.
if you don't care about every little bit of efficiency (i assume this is to experiment, and not for real use?) just reallocate and pad (in practice, you could round up and calloc when you first declare these):
size_t round16(size_t n) {
// if n isn't a multiple of 16, round up to next multiple
if (n % 16) return 16 * (1 + n / 16);
return n;
}
size_t realloc16(uint8_t **data, size_t len) {
// if len isn't a multiple of 16, extend with 0s to next multiple
size_t n = round16(len);
*data = realloc(*data, n);
for (size_t i = len; i < n; ++i) (*data)[i] = 0;
return n;
}
void xor16(uint8_t *result, uint8_t *a, uint8_t *b) {
// 16 byte xor
for (size_t i = 0; i < 16; ++i) result[i] = a[i] ^ b[i];
}
void xorandmult(uint8_t *x, uint8_t *data, size_t n, unint8_t *h) {
// run along the length of the (extended) data, xoring and mutliplying
uint8_t tmp[16];
for (size_t i = 0; i < n / 16; ++i) {
xor16(tmp, x, data+i*16);
multgcm(x, h, tmp);
}
}
void ghash(uint8_t *x, uint8_t **a, size_t len_a, uint8_t **c, size_t len_c, uint8_t *h) {
size_t m = realloc16(a, len_a);
xorandmult(x, *a, m, h);
size_t n = realloc16(c, len_c);
xorandmult(x, *c, n, h);
// then handle lengths
}
uint8_t x[16] = {0};
ghash(x, &a, len_a, &c, len_c, h);
disclaimer - no expert, just skimmed the spec. code uncompiled, unchecked, and not intended for "real" use. also, the spec supports arbitrary (bit) lengths, but i assume you're working in bytes.
also, i am still not sure i am answering the right question.
I need to swap every two adjacent bits as a generic operation which will do so for every variable type given.
I thought of the needed masks and operations for every single byte:
(var & 0x55) << 1 | (var & 0xAA) >> 1
But how do I make this apply for let's say an integer?
Do I need to create an array of sizeof(int) unsigned chars with the above masks and apply the operation that way?
You can do this byte by byte (the same as char by char).
For example:
int n = 0xAA55A55A;
unsigned char *p = (unsigned char *) &n;
for (; p < (unsigned char *) &n + sizeof(n); p++)
*p = (*p & 0x55) << 1 | (*p & 0xAA) >> 1;
Two suggestions:
Instead of using the logic operations, you can use a look up table of 256 chars.:
char lookUpTable[256] = {0x00, 0x02, 0x01 ...};
If you dont want to initialize this lookup statically, you can write a function that initialize it using logic operations.
When you want to swap byte b, you either simply write lookUpTable[b], or you wrap this with a function.
As for swapping any type, you write a function that does something like:
void SwapBits(char* data, size_t len)
{
For (; len > 0; len--)
{
*data = lookUpTable[*data];
data++;
}
}
You then use this like this:
AnyType swapMe = whatever;
SwapBits((char*)(&swapMe), sizeof(AnyType));
Note this replaces the "contents" of swapMe.
One more thing, the right shift behavior is architecrure specific, some architectures may sign extend on right shift. It would be more generic to use an expression like:
SwappedByte = ((Byte >> 1)&0x55) | ((Byte << 1)&0xaa)
As this way you remove any sign extension artifacts.
Something like this. Cast the address of any variable to a char * and you can iterate over the bytes.
#include <stdio.h>
char swap_c(char);
void swap_r(char *, int);
int main(void) {
char c = 10;
c = swap_c(c);
printf("%i\n", c);
int i = 10;
char * r = (char *) &i; //you can cast the address of any variable into a char *
swap_r(r, sizeof(int));
printf("%i\n", i);
}
void swap_r(char * c, int length) {
int i = 0;
while(i < length) {
c[i] = swap_c(c[i]);
i++;
}
}
char swap_c(char c) {
return (c & 0x55) << 1 | (c & 0xAA) >> 1;
}
//1010
//0101
Briefly: Question is related to bitwise operations on hex - language C ; O.S: linux
I would simply like to do some bitwise operations on a "long" hex string.
I tried the following:
First try:
I cannot use the following because of overflow:
long t1 = 0xabefffcccaadddddffff;
and t2 = 0xdeeefffffccccaaadacd;
Second try: Does not work because abcdef are interpreted as string instead of hex
char* t1 = "abefffcccaadddddffff";
char* t2 = "deeefffffccccaaadacd";
int len = strlen(t1);
for (int i = 0; i < len; i++ )
{
char exor = *(t1 + i) ^ *(t2 + i);
printf("%x", exor);
}
Could someone please let me know how to do this? thx
Bitwise operations are usually very easily extended to larger numbers.
The best way to do this is to split them up into 4 or 8 byte sequences, and store them as an array of uints. In this case you need at least 80 bits for those particular strings.
For AND it is pretty simple, something like:
unsigned int A[3] = { 0xabef, 0xffcccaad, 0xddddffff };
unsigned int B[3] = { 0xdeee, 0xfffffccc, 0xcaaadacd };
unsigned int R[3] = { 0 };
for (int b = 0; b < 3; b++) {
R[b] = A[b] & B[b];
}
A more full example including scanning hex strings and printing them:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef unsigned int uint;
void long_Print(int size, const uint a[]) {
printf("0x");
for (int i = 0; i < size; i++) {
printf("%x", a[i]);
}
}
void long_AND(int size, const uint a[], const uint b[], uint r[]) {
for (int i = 0; i < size; i++) {
r[i] = a[i] & b[i];
}
}
// Reads a long hex string and fills an array. Returns the number of elements filled.
int long_Scan(int size, const char* str, uint r[]) {
int len = strlen(str);
int ri = size;
for (const char* here = &str[len]; here != str; here -= 8) {
if (here < str) {
char* tmp = (char*)malloc(4);
tmp[0] = '%';
tmp[1] = (char)(str - here + '0');
tmp[2] = 'x';
tmp[3] = '\0';
sscanf(str, tmp, &r[ri--]);
free(tmp);
break;
}
else {
sscanf(here, "%8x", &r[ri--]);
}
}
for (; ri >= 0; ri--) {
r[ri] == 0;
}
return size - ri;
}
int main(int argc, char* argv[])
{
uint A[3] = { 0 };
uint B[3] = { 0 };
uint R[3] = { 0 };
long_Scan(3, "abefffcccaadddddffff", A);
long_Scan(3, "deeefffffccccaaadacd", B);
long_Print(3, A);
puts("\nAND");
long_Print(3, B);
puts("\n=");
long_AND(3, A, B, R);
long_Print(3, R);
getchar();
return 0;
}
You'll certainly need to use a library that can handle arbitrarily long integers. Consider using libgmp: http://gmplib.org/
Before you can do any sort of bitwise operations, you need to be working with integers. "abeffccc" is not an integer. It is a string. You need to use something like strtol
to first convert the string to an integer.
If your values are too big to fit into a 64-bit long long int (0xFFFFFFFF,FFFFFFFF) then you'll need to use a Big Integer library, or something similar, to support arbitrarily large values. As H2CO3 mentioned, libgmp is an excellent choice for large numbers in C.
Instead of using unsigned long directly, you could try using an array of unsigned int. Each unsigned int holds 32 bits, or 8 hex digits. You would therefore have to chop-up your constant into chunks of 8 hex digits each:
unsigned int t1[3] = { 0xabef , 0xffcccaad , 0xddddffff };
Note that for sanity, you should store them in reverse order so that the first entry of t1 contains the lowest-order bits.