Convert char array elements into Hexadecimal equivalent in C code - arrays

I'm currently trying to create a custom function in C code that would take an unsigned char array like: array[] = "11000000111111111000000010000000" as the input and convert this into 0xC0FF8080 and either store this back into array or simply printf to the console. Any help in clearing up my confusion on this would be greatly appreciated. Thanks!

Iterate over the string, and with each iteration shift the result to the left and set the right-most bit to the appropriate value:
#include <stdio.h>
#include <string.h>
int main(void)
{
char const array[] = "11000000111111111000000010000000";
size_t const length = strlen(array);
unsigned long long n = 0ULL;
for (size_t idx = 0U; idx < length; ++idx)
{
n <<= 1U;
n |= array[idx] == '0' ? 0U : 1U;
// n |= array[idx] - '0'; // An alternative to the previous line
}
printf("%#llx\n", n);
}
This uses a (signed) char array, but the method is the same.
Storing the result back into the char array:
#include <stdio.h>
#include <string.h>
int main(void)
{
char array[] = "11000000111111111000000010000000";
size_t length = strlen(array);
for (size_t idx = 0U; idx < length; ++idx)
array[idx] = array[idx] - '0';
for (size_t idx = 0U; idx < length; ++idx)
printf("%d", array[idx]);
putchar('\n');
}
Note that here the char types will hold the decimal values 0 and 1.

Related

How can I join the values of each array element inside a for loop together in c?

#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main ()
{
char *hexstring = "deadbeef"; //storing the hexadecimal value
int i;
unsigned int bytearray[12]; //variable to store the new output.
uint8_t str_len = strlen(hexstring); //calculates length of the hexstring
for (i = 0; i < (str_len / 2); i++)
{
sscanf(hexstring + 2*i, "%02x", &bytearray[i]);
printf("bytearray %d: %02x\n", i, bytearray[i]);
}
return 0;
}
Output shown currently :
bytearray 0: de
bytearray 1: ad
bytearray 2: be
bytearray 3: ef
To do: I want to merge/combine/put together the arrays such that bytearray[0] bytearray[1] bytearray[2] bytearray[3] , i.e., deadbeef output can be seen again after the for loop?
You probably want this:
int db = 0;
for (i = 0; i < (str_len / 2); i++)
{
db <<= 8; // shift 8 bits to the left
db |= bytearray[i]; // copy bytearray[i] into 8 lower bits of db
}
printf("%08x\n", db);

Find the difference between elements in an array and store the results in a new array

This is my current code:
#include <stdio.h>
int index_x[] = {0,0,1,0,1,0,0,0,1,0,0,1,0}; // any number of elements
int len = sizeof index_x / sizeof*index_x;
int main(void) {
int arr[len];
int j = 0;
for (int i = 0; i < len; i++)
if (index_x[i])
arr[j++] = i; // save and advance j only if value is "1"
for (int i = 0; i < j; i++) // only print below j !
printf("%d\n", arr[i]);
}
Output:
2
4
8
11
From this output, I would like to generate another array that is the difference between these elements. In this case the new array would be {2,4,3}. (2-4=2, 8-4=4, 11-8=3).
I am currently struggling with two things:
Saving the array generated from the current code arr[i] as a another array so I can manipulate it for future uses.
Generating the "differences array". The tricky part is that the number of elements will not be constant so I cannot specify an array size.
It may be helpful to break things out into functions.
int indexes_of_non_zero(int *source, size_t len, int **dest) {
*dest = malloc(sizeof(int) * len);
int count = 0;
for (int i = 0; i < len; i++) {
if (source[i] != 0) {
(*dest)[count++] = i;
}
}
*dest = realloc(*dest, sizeof(int) * count);
return count;
}
So we have a function indexes_of_non_zero that takes a source array of ints with size specified by argument len, and then a pointer to an array of ints that will be the destination for our output.
We can naively allocate the same amount of memory to the destination, then loop over the source array and store the indexes of non-zero elements. When we're done, we use count to know the size of destination array. We use realloc to shrink the array to just the needed size. And the key is we return the count so our main function knows how big the destination array is.
We can now create a diffs function to do basically the same thing for the differences.
int diffs(int *source, size_t len, int **dest) {
*dest = malloc(sizeof(int) * (len - 1));
for (int i = 0; i < (len - 1); i++) {
(*dest)[i] = abs(source[i] - source[i + 1]);
}
return len - 1;
}
Putting it all together (not copying and pasting the function implementations for terseness) with a main function, and remembering to free the memory we've used, we get:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int indexes_of_non_zero(int *source, size_t len, int **dest);
int diffs(int *source, size_t len, int **dest);
int main(void) {
int data[] = {0,0,1,0,1,0,0,0,1,0,0,1,0};
size_t len = sizeof(data) / sizeof(*data);
int *nz = NULL;
int *d = NULL;
int nzc = indexes_of_non_zero(data, len, &nz);
int dlen = diffs(nz, nzc, &d);
for (int i = 0; i < nzc; i++) {
printf("%d\n", nz[i]);
}
for (int i = 0; i < dlen; i++) {
printf("%d\n", d[i]);
}
free(nz);
free(d);
}
And compiling and running it, the output is:
2
4
8
11
2
4
3
I changed it to get the differences as direct as possible; the inner loop is very simple.
The size question, first part: I (still) tried to avoid size_t for the input but added some sanity check for the size. Just to show there is a limit.
part two: a first loop to get the sum of true values in advance. Also the booldata array consists of chars and is not called index_x. Index is i.
part three: the diffs VLA gets its exact size, which can be 0 even for huge inputs. Some test could be added here after counting, to rule out a (big) input full of "1".
I added the copying, with message and printout.
#include <stdio.h>
#include <string.h>
char booldata[] = { 0,0,1,0,1,0,0,0,1,0,0,1,0 };
char sz_overf = sizeof booldata > 0xffffL * 0xffff; // too-big-flag for exiting...
int len = sizeof booldata / sizeof * booldata; // ...to keep len below size_t
int sum_of_trues (char *booldata, int len) {
int sum = 0;
for (int i = 0; i < len; i++)
if (booldata[i])
sum++;
return sum;
}
void print_intarr(int *inta, int len) {
for (int i = 0; i < len; i++)
printf("%d\n", inta[i]);
}
int main(void)
{
if (sz_overf) return 100; // len might be overflowed
int unsigned // signed provokes VLA warning: 9 gazillions seems ok, but not 18
dsum = sum_of_trues(booldata, len) - 1; // Invest a counting loop
int diffs[dsum], // VLA
di = 0; // diffs' index
int sti = -1; // Stored last index containing true
for (int i = 0; i < len; i++)
if (booldata[i]) { // true?
if (sti >= 0) { // and is there a left neighbour?
int diff = i - sti; // how far away?
printf("%d\n", diff); // 1. on-the-fly result
diffs[di++] = diff; // 2. for keeps
}
sti = i; // remember last "true"
}
printf("Copying %zu bytes from Diff.-Array\n", sizeof diffs);
int diffscopy[sizeof diffs];
memcpy(diffscopy, diffs, sizeof diffs);
print_intarr(diffscopy, dsum); // dsum or sizeof diffs
return 0;
}
output:
2
4
3
Copying 12 bytes from Diff.-Array
2
4
3
The inner loop could look like this w/o multi-option:
if (booldata[i]) {
if (sti >= 0) // and is there a left neighbour?
diffs[di++] = i - st; // 2. for keeps
sti = i;
}
Two arrays and three variables. The rest is needed to make this work.
BUGS: all-false input segfaults. It takes one "true" to get zero diffs...

Split int into char array in C

I have an int, and I need to split it to a char array, so 2 chars in each array position. After that, I need to do the opposite process. This is the best I could come up with, but I still couldn't make it work. Any suggestions?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int length = 10968;
int bytesNeeded = sizeof(length) / 2;
char *controlPacket = (char*)malloc(sizeof(char*)*bytesNeeded);
for (int i = 0; i < bytesNeeded; i++)
{
controlPacket[i] = (length >> (8* i));
}
int newSize = 0;
for (int i = 0; i < bytesNeeded; i++)
{
newSize += (controlPacket[i] << (8 * i));
}
printf("Newsize is: %d\n", newSize);
}
Change the variables that you're performing bitwise operations on to unsigned, and also mask the result of shifting before assigning to the array. Otherwise, you get overflow, which causes incorrect results (maybe undefined behavior, I'm not sure).
You also shouldn't divide sizeof(length) by 2. It will work for values that only use the low order half of the number, but not for larger values; e.g. if you use length = 1096800; the result will be 48824.
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned int length = 10968;
int bytesNeeded = sizeof(length);
unsigned char *controlPacket = malloc(sizeof(unsigned char)*bytesNeeded);
for (int i = 0; i < bytesNeeded; i++)
{
controlPacket[i] = (length >> (8* i) & 0xff);
}
unsigned int newSize = 0;
for (int i = 0; i < bytesNeeded; i++)
{
newSize += (controlPacket[i] << (8 * i));
}
printf("Newsize is: %d\n", newSize);
free(controlPacket);
}

Segmentation Fault in C (array related)

I wrote a code in c in order to solve Project Euler Problem 45 (https://projecteuler.net/problem=45). I keep getting segmentation fault error 139. I am sure it is not about trying to access a memory location that I do not have permission for.
My guessing is , the problem is related to sizes of my arrays. I looked up the answer and it is some 10 digit number. To get that ten digit number the size of the array "triangle" has to be something between one million and two million. But when I make the array that big i get the error. I don't get the error in the code below since size of that array is 500 000 (but of course that is not enough).
I use ubuntu 16.04 and Geany.
If you need more information please ask. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
unsigned long pentagonalgenerator(int n);
unsigned long trianglegenerator(int n);
unsigned long hexagonalgenerator(int n);
_Bool search_function(unsigned int to_be_looked_for , unsigned long array[] , int sizeofarray);
int main(void)
{
unsigned long pentagon[28000] = {0};
int sizeofpentagon = 28000;
unsigned long hexagon[100000] = {0};
int sizeofhexagon = 100000;
unsigned long triangle[500000] = {0};
int sizeoftriangle = 500000;
int counter;
for(counter = 0 ; counter < sizeofpentagon ; counter++)
{
pentagon[counter] = pentagonalgenerator(counter + 2);
}
for(counter = 0 ; counter < sizeofhexagon ; counter++)
{
hexagon[counter] = hexagonalgenerator(counter + 2);
}
for(counter = 0 ; counter < sizeoftriangle ; counter++)
{
triangle[counter] = trianglegenerator(counter + 2);
}
printf("%lu \n%lu \n%lu \n", hexagon[sizeofhexagon - 1] , pentagon[sizeofpentagon - 1] , triangle[sizeoftriangle - 1]);
for(counter = 0 ; counter < sizeofhexagon ; counter++)
{
if(search_function(hexagon[counter] , pentagon , sizeofpentagon))
{
if(search_function(hexagon[counter] , triangle , sizeoftriangle) && hexagon[counter] != 40755)
{
printf("%lu", hexagon[counter]);
return 0;
}
}
}
return 1;
}
_Bool search_function(unsigned int to_be_looked_for , unsigned long array[] , int sizeofarray)
{
int left = 0, right = sizeofarray - 1 , middle = 0;
while(left <= right)
{
middle = (left + right) / 2;
if(to_be_looked_for == array[middle]) return 1;
else if(to_be_looked_for < array[middle]) right = middle - 1;
else if(to_be_looked_for > array[middle]) left = middle + 1;
}
return 0;
}
unsigned long pentagonalgenerator(int n)
{
unsigned int return_value = 0;
return_value = (n*(3*n - 1)) / 2;
return return_value;
}
unsigned long hexagonalgenerator(int n)
{
unsigned int return_value = 0;
return_value = n*(2*n - 1);
return return_value;
}
unsigned long trianglegenerator(int n)
{
unsigned int return_value = 0;
return_value = (n*(n + 1)) / 2;
return return_value;
}
That's a lot of memory for the stack. Instead of this
unsigned long pentagon[28000] = {0};
int sizeofpentagon = 28000;
unsigned long hexagon[100000] = {0};
int sizeofhexagon = 100000;
unsigned long triangle[500000] = {0};
int sizeoftriangle = 500000;
Try this:
unsigned long *pentagon = calloc(28000*sizeof(unsigned long));
int sizeofpentagon = 28000;
unsigned long *hexagon = calloc(100000 * sizeof(unsigned long));
int sizeofhexagon = 100000;
unsigned long *triangle = calloc(500000 * sizeof(unsigned long));
int sizeoftriangle = 500000;
You have very large arrays defined as local variables in the stack. You are getting a stack overflow because of that. Arrays pentagon hexagon triangle are very large.
These need to be moved to the global space or they should be dynamically allocated. For your use case, it is easier to move the arrays to global.
unsigned long pentagon[28000] = {0};
unsigned long hexagon[100000] = {0};
unsigned long triangle[500000] = {0};
int main(void)
{
int sizeofpentagon = 28000;
int sizeofhexagon = 100000;
int sizeoftriangle = 500000;
....
The maximum size for automatic variables is an implementation dependent detail. BUT major implementation have options to set it.
For example, if you are using gcc or clang, automatic variables are stored in the stack, and the stack size is controlled at link time by the option --stack <size>. The default size is 2Mb and your arrays require 628000 unsigned long so at least 5Mb.
Provided you have more standard requirements in other places of this code, I would try a 8Mb stack:
cc myprog.c -Wl,--stack -Wl,0x800000 -o myprog
(-Wl, is used to pass the argument to the linker phase of the build).
This avoids to reformat your code (for examble using allocated arrays) to only solve a compilation problem.

How to split an array in c?

I need a logic to acheive my target. I've buffer array size of 38400. This array data can be filled by a controller. Here i have to obtain an AES algorithm. In that i've to read 16 bytes of data from the buffer then encrypt, upto end of buffer. How to spilt an array into 16 bytes and encrypt? . I used following logic but i can't get it right now ?
unsigned char ptext[16] = "Attack at dawn!";
unsigned char ctext[16];
unsigned char decptext[16];
unsigned char buffer[120*160*2];
for (int count = 0; count < 120*160*2; count ++)
buffer[count] = count + 1;
for (i = 0; i < 120*160*2; i ++)
{
ptext[i]= buffer[i];
if(i%15 == 0)
{
aes_encrypt(ctx, ptext, ctext);
for(k = 0; k<=i; k++)
{
ptext[k]='\0';
}
}
}
void aes_encrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16])
{
int i;
// copy input to state
for(i = 0; i < 16; i++)
ctx->state[i & 0x03][i >> 2] = input[i];
aes_addroundkey(ctx, 0);
for(i = 1; i < ctx->rounds; i++) {
aes_subbytes(ctx);
aes_shiftrows(ctx);
aes_mixcolumns(ctx);
aes_addroundkey(ctx, i);
}
aes_subbytes(ctx);
aes_shiftrows(ctx);
aes_addroundkey(ctx, ctx->rounds);
// copy state to output
for(i = 0; i < 16; i++)
{
output[i] = ctx->state[i & 0x03][i >> 2];
printf("%c",output[i]);
}
}
Note: I've filled buffer[] with random numbers.
Me only have to know how to split an array.
Thanks in Advance.
You don't need to "split" the array (whatever "split" means for you.) Just operate on every 16-byte segment of it:
void process_segment(unsigned char segment[])
{
// Work on the first 16 bytes of 'segment'.
}
// ...
unsigned char buffer[120*160*2];
for (size_t i = 0; i < 120*160*2; i += 16) {
process_segment(buffer + i);
}
The above is just an example. If you want a nested for loop instead, you'd do something like this:
unsigned char buffer[120*160*2];
for (size_t i = 0; i < 120*160*2; i += 16) {
unsigned char* segment = buffer + i;
// Work on the first 16 bytes of 'segment'.
for (size_t j = 0; j < 16; ++j) {
// Work on segment[j].
}
}
You should probably change your aes_encrypt() function to take an unsigned char input[] instead of an unsigned char input[16] so that you can pass segment to it.
The code you posted would then become something like this:
unsigned char ptext[16] = "Attack at dawn!";
unsigned char ctext[16];
unsigned char decptext[16];
unsigned char buffer[120*160*2];
for (int count = 0; count < 120*160*2; count++)
buffer[count] = count + 1;
for (i = 0; i < 120*160*2; i += 16) {
unsigned char *segment = buffer + i;
aes_encrypt(ctx, segment, ctext);
// Clear the current 16-byte segment.
memset(segment, '\0', 16);
// ctext now contains the encrypted data of the current
// 16-byte segment. I assume you want to save it somewhere
// now since it will be overridden in the next iteration of
// the loop.
}
And the signature of your aes_encrypt() function would become:
void aes_encrypt(aes_ctx_t *ctx, unsigned char input[],
unsigned char output[16])

Resources