Convert char array to hex array - c

Input:
char arr1[9] = "+100-200" // (+ is 2B, - is 2D, 1 is 31 and 2 is 32)
Output:
unsigned int arr2[4]= [0x2B31,0x3030,0x2D32,0x3030]
How can I do this?

Your question seems inconsistent: 0 should convert to 0x30, its ASCII value.
Why this modification, the code is quite straightforward:
char arr1[8] = "+100-200";
unsigned int arr2[4];
for (int i = 0; i < 8; i += 2) {
arr2[i / 2] = ((unsigned int)(unsigned char)arr1[i] << 8) |
(unsigned int)(unsigned char)arr1[i + 1];
}
for (int i = 0; i < 4; i++) {
printf("0x%04X ", arr2[i]);
}
printf("\n");
Output:
0x2B31 0x3030 0x2D32 0x3030

Related

How to concatenate bit by bit in c?

I have matrix of '1' and '0' with the dimensions 8x8. I need to store the whole matrix in one unsigned long long variable bit by bit. How can i do that?
For example, let's take the matrix of '1' and '0' that is 2x2:
The matrix 2x2:
1 0
0 1
The variable must contain: 1001 in bits.
The same example, but over the matrix 8x8 and unsigned long long variable.
That's what i've tried to do:
#include <stdio.h>
int main()
{
unsigned long long result = 0;
char matrix[8][8]; // lets that the matrix is already filled by '1' and '0'
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
result = result | ((unsigned long long)(matrix[i][j] - '0'));
result <<= 1;
}
}
return 0;
}
Is it right? I implemented this nested loop in my algorithm and that didn't work properly.
Converting the text representation of an integer into its integer value can be done using strtoull().
char buf[sizeof(matrix)+1];
memcpy(buf, matrix, sizeof(matrix));
buf[sizeof(matrix)] = '\0';
result = strtoull(buf, NULL, 2);
try this
const int mx_size = 8;
int main() {
unsigned long long result = 0;
bool matrix[8][8]; // lets that the matrix is already filled by '1' and '0'
for (int i =0; i < mx_size; ++i)
matrix[i][i] = 1;
for (int i = 0; i < mx_size; i++) {
for (int j = 0; j < mx_size; j++) {
result |= (unsigned long long)matrix[i][j] << (i*mx_size + j);
}
}
return 0;
}
Here you have the code (a bit more
#include <stdio.h>
#include <stdint.h>
uint64_t convert(char matrix[8][8], int order, char zero)
{
uint8_t byte;
uint64_t result = 0;
for(size_t row = 0; row < 8; row++)
{
byte = 0;
for(size_t column = 0; column < 8; column++)
{
byte <<= 1;
byte |= matrix[row][column] != zero ? 1 : 0; //anything != defined zero char is 1
}
if (order)
{
result |= (uint64_t)byte << (8 * row);
}
else
{
result |= (uint64_t)byte << (56 - 8 * row);
}
}
return result;
}
int main(void) {
char matrix[8][8] =
{
{'1','0','1','0','1','0','1','0'},
{'0','1','0','1','0','1','0','1'},
{'1','1','1','0','0','0','1','1'},
{'0','0','0','1','1','1','0','0'},
{'1','1','1','1','1','0','0','0'},
{'0','0','0','0','1','1','1','1'},
{'1','1','0','0','1','1','0','0'},
{'0','0','1','1','0','0','1','1'},
};
unsigned long long result = convert(matrix, 0, '0');
for(size_t index = 0; index < 64; index ++)
printf("%1d", !!(result & (1ULL << index)));
printf("\n");
result = convert(matrix,1, '0');
for(size_t index = 0; index < 64; index ++)
printf("%1d", !!(result & (1ULL << index)));
printf("\n");
return 0;
}

Integer conversion to Hexadecimal String in C without (sprintf/printf libraries) [duplicate]

This question already has answers here:
How can I convert an integer to a hexadecimal string in C?
(7 answers)
Closed 5 years ago.
I have these input variables:
uint16 temperature = 0x1f12;
uint8 array[8] = {0,0,0,...0}
And I want to have
array8[0] = '1';
array8[1] = 'f';
array8[2] = '1';
array8[3] = '2';
array8[4] = '\0';
array8[5] = '\0';
array8[6] = '\0';
array8[7] = '\0';
However, for memory problems (I'm working with microcontrollers!) I need to avoid functions such as sprintf, printf, puts, etc.
How should I do?
Best regards,
Use recursion to determine 1 hex digit at a time.
// print digit at the end and return the next address
static char *itohexa_helper(char *dest, unsigned x) {
if (x >= 16) {
dest = itohexa_helper(dest, x/16);
}
*dest++ = "0123456789abcdef"[x & 15];
return dest;
}
char *itohexa(char *dest, unsigned x) {
*itohexa_helper(dest, x) = '\0';
return dest;
}
int main(void) {
char array[8];
uint16_t temperature = 0x1f11;
puts(itohexa(array, temperature));
puts(itohexa(array, 0));
puts(itohexa(array, 0x1234567));
puts(itohexa(array, UINT_MAX & 0xFFFFFFF));
}
Output
1f11
0
1234567
fffffff
This code uses only 8 additional bytes in stack(int i, j).
int i;
for (i = 0; i < 8; i++) {
array[7 - i] = temperature % 16;
temperature /= 16;
if (temperature == 0)
break;
}
if (i == 8)
i--;
int j;
for (j = 0; j <= i; j++)
array[j] = array[7 - i + j];
for (j = i + 1; j < 8; j++)
array[j] = 0;
for (j = 0; j < 8; j++)
if (array[j] < 10)
array[j] += '0';
else
array[j] += 'a' - 10;
This code first converts temperature = 0x1f12 to array[8] = { 0, 0, 0, 0, 1, 15, 1, 2}.
Then shifts the elements of array so that it becomes array[8] = { 1, 15, 1, 2, 0, 0, 0, 0 }.
And then converts the numbers to corresponding characters: array[8] = { '1', 'f', '1', '2', '0', '0', '0', '0' }.
Note also that this if condition
if (i == 8)
i--;
is never met, since break condition always suffices in the first for loop, even for temperature >= 0x10000000. It's just there in the hope that it might help someone understand this code.
int convert()
{
uint16_t temperature = 0x1f11;
uint8_t array[8] = {0,0,0,0,0,0,0,0};
int i = 0;
for(i = 0; i < 8; i++){
array[i] = (0xf000 & temperature) >> 12 ;
temperature <<= 4;
printf("array[%d] = %x\n", i ,array[i]);
}
return(0);
}

How can I encode four 16 bit uints into a 64 bit uint, and decode them again?

I wrote this function with the help of this page on bit twiddling:
uint16_t *decode(uint64_t instr) {
// decode instr (this is new to me lol)
uint16_t icode = (instr >> 48) & ((1 << 16) - 1);
uint16_t p1 = (instr >> 32) & ((1 << 16) - 1);
uint16_t p2 = (instr >> 16) & ((1 << 16) - 1);
uint16_t p3 = (instr >> 00) & ((1 << 16) - 1);
return (uint16_t[]){icode, p1, p2, p3};
}
I have this to test it:
uint16_t *arr = decode(number);
for(int i = 0; i < 4; i++) {
printf("%d\n", arr[i]);
}
However, this prints 0 four times whatever number is. I also haven't solved the first part of the question, how to encode the four uint16_t's in the first place.
how to encode the four uint16_t's in the first place
This isn't hard. All you have to do is to load each uint16_t to a uint64_t one-by-one, and then return that uint64_t:
uint64_t encode(uint16_t uints[]) {
uint64_t master = 0;
for (uint8_t index = 0; index <= 3; ++index) {
master <<= 16; // Shift master left by 16 bits to create space for the next uint16
master |= uints[index]; // Load uints[index] to the lower 16 bits of master
} // Do this four times
return master;
}
To load the uint16_ts in reverse order, simply replace uint8_t index = 0; index <= 3; ++index with uint8_t index = 3; index >= 0; --index.
Your best bet is actually to use memcpy. Most modern compilers will optimize this into the necessary bit shifts and such for you.
uint64_t pack(const uint16_t arr[static 4]) {
uint64_t res;
memcpy(&res, arr, 8);
return res;
}
void unpack(uint64_t v, uint16_t arr[static 4]) {
memcpy(arr, &v, 8);
}
Note that the result is endian-dependent, appropriate for packing and unpacking on the same machine. Note too that I'm using the static array specifier to check that the caller passes at least 4 elements (when such checking is possible); if that gives your compiler grief, just remove the static specifier.
First, you can't pass an array back from a function the way you currently have it (which is why you're getting 0's), you'll need to pass it via pointer or static reference.
However, since you're dealing with 2 known bit-widths, you can use a mask and shift off that:
out[0] = val & 0x000000000000FFFF; // 1st word
out[1] = (val & 0x00000000FFFF0000) >> 16; // 2nd word
out[2] = (val & 0x0000FFFF00000000) >> 32; // 3rd word
out[3] = (val & 0xFFFF000000000000) >> 48; // 4th word
You could put this in a function or macro:
#define MACRO_DECODE(val, arr) arr[0]= val & 0x000000000000FFFF; \
arr[1] = (val & 0x00000000FFFF0000) >> 16; \
arr[2] = (val & 0x0000FFFF00000000) >> 32; \
arr[3] = (val & 0xFFFF000000000000) >> 48;
void decode(uint64_t val, uint16_t *out)
{
out[0] = val & 0x000000000000FFFF;
out[1] = (val & 0x00000000FFFF0000) >> 16;
out[2] = (val & 0x0000FFFF00000000) >> 32;
out[3] = (val & 0xFFFF000000000000) >> 48;
}
int main(int argc, char** argv)
{
int i;
uint16_t arr[] = { 0, 0, 0, 0} ;
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
// as a function
decode(0xAAAABBBBCCCCDDDD, arr);
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
// as a macro
MACRO_DECODE(0xDDDDCCCCBBBBAAAA, arr);
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
return 0;
}
Additionally, you could use memcpy:
int main(int argc, char** argv)
{
int i;
uint16_t arr[] = { 0, 0, 0, 0} ;
uint64_t src = 0xAAAABBBBCCCCDDDD;
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
// memcpy
memcpy(arr, &src, sizeof(arr));
for (i = 0; i < 4; ++i) {
printf("%#06x = %d\n", arr[i], arr[i]);
}
return 0;
}
Hope that can help.

How to retrieve value from bytes stored in a byte array?

I am trying to store 8 bytes in a byte array to store the value of a pointer.
int main() {
unsigned long a = 0;
char buf[8];
int i = 0;
int *p = &i;
a = (unsigned long)p;
while (i < 8)
{
buf[i] = (a >> (8 * i)) & 0xFF;
i++;
}
a = 0;
i = 0;
while (i < 8)
{
a = ?
i++;
}
p = (int *)a;
}
The first loop stores successive bytes of p, as casted into usigned long in a, but I don't know how to retrieve the value in the second loop. Does somebody have a clue?
This is the inverse code to yours:
a = 0;
while (i < 8)
{
a |= ((unsigned long)buf[i] & 0xff ) << (8 * i);
i++;
}

Standard algorithm for WEP key generator 64-bit

I have downloaded the following function from the internet. It's a WEP Key generator for 64-bit from a given passphrase, and I am wondering if a such algorithm is a standard algorithm or if it's an algorithm invented by the developer?
void wepkey64(char *passphrase, unsigned char k64[4][5])
{
unsigned char pseed[4] = {0};
unsigned int randNumber, tmp;
int i, j;
for(i = 0; i < strlen(passphrase); i++)
{
pseed[i%4] ^= (unsigned char) passphrase[i];
}
randNumber = pseed[0] | (pseed[1] << 8) | (pseed[2] << 16) | (pseed[3] << 24);
for (i = 0; i < 4; i++)
{
for (j = 0; j < 5; j++)
{
randNumber = (randNumber * 0x343fd + 0x269ec3) & 0xffffffff;
tmp = (randNumber >> 16) & 0xff;
k64[i][j] = (unsigned char) tmp;
}
}
}

Resources