binary int* array to int equivalent - c

I am quite new to C programming and am wondering whether there is a method in a pre-existent library that can help me in this particular situation or whether I need to write my own method to achieve the desired results.
Essentially, I will have an int* array representing a binary number. For example:
|1|0|1|1|
Ideally, I would like 11 to be returned from this array.
Is there are method in C that takes an int* array and returns the int equivalent of the numbers stored in it? Or is this something I need to write

This is something you will need to write yourself.
Since there are no common real life use cases for representing numbers this way, the C standard library has no function to handle it.
However, this is a good exercise for learning about bit shifts.
Read up on << and >> operators.

No, you must do it by yourself. With << operator.

My implementation
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
uint8_t u8_from_ubits(uint8_t* bits)
{
int i;
uint8_t num = 0;
for(i = 0; i < 8; i++)
num |= bits[7-i] << i; //8-1=7
return num;
}
uint8_t bits[8] = {
0,0,0,0,1,0,1,1
};
int main()
{
printf("%d\n",u8_from_ubits(bits));
return 0;
}
For more bit count just change bit number in function

Related

is thare a way to convert a int into binary and put it into a array

I am making a program for my arduino that needs to access a eeprom but I need to find a way to send it a address, I have a int I would like to convert into binary and send to the eeprom but I need to split it into a array so I can send the data to the eeprom.
I cant think of any way to do this and I have asked some people for help but they couldn't figure out how to ether.
void int_to_bin_array(unsigned int in, int count, int* out)
{
unsigned int mask = 1U << (count-1);
int i;
for (i = 0; i < count; i++) {
out[i] = (in & mask) ? 1 : 0;
in <<= 1;
}
}
int main(void)
{
int binary_array[8];
const int bin_size = 8;
int decimal = 15;
int_to_bin_array(decimal, bin_size, binary_array);
return 0;
}
Memory addresses are hexadecimal values, not binary. You don't need to do this here.
You need to correctly understand memory interfacing with your MCU (Arduino in this case) along with embedded systems concepts and pointers in C.
You can specify address values in hexadecimal values directly (uint_t addr = (uint_t *) 0x1234ABCD) and the compiler will automatically convert it to respective binary, during compilation.

Another invert char array in C

That code will run on a payment device (POS). I have to use legacy C (not C# or C++) for that purpose.
I am trying to prepare a simple Mifare card read/write software data. Below document is my reference and I am trying to achieve what is on page 9, 8.6.2.1 Value blocks explains.
http://www.nxp.com/documents/data_sheet/MF1S50YYX_V1.pdf
I just know very basics of C. All my searches in The Internet have failed. According to document:
1- There is integer variable with value of 1234567.
2- There is char array[4] which should have hex of above value which is 0x0012D687
3- I am supposed to invert that char array[4] and reach value of 0xFFED2978
I need to do some other things but I have stuck in number 3 above. What I have tried lastly is
int value = 1234567;
char valuebuffer[4];
char invertbuffer[4];
sprintf(valuebuffer, "%04x", value);
for(i = 0; i < sizeof(valuebuffer); i++ )
{
invertbuffer[i] ^= valuebuffer[i];
}
When I print, I read some other value in invertbuffer and not 0xFFED2978
Seems like you're making it more complicated than it needs to be. You can do the binary inversion on the int variable rather than messing around with individual bytes.
int value = 1234567;
int inverted= ~ value;
printf("%x\n",value);
printf("%x\n",inverted);
gives you output of
12d687
ffed2978
First of all, you must use the types from stdint.h and not char, because the latter has implementation-defined signedness and is therefore overall unsuitable for holding raw binary data.
With that sorted, you can use a union for maximum flexibility:
#include <stdint.h>
#include <stdio.h>
typedef union
{
uint32_t u32;
uint8_t u8 [4];
} uint32_union_t;
int main (void)
{
uint32_union_t x;
x.u32 = 1234567;
for(size_t i=0; i<4; i++)
{
printf("%X ", x.u8[i]);
}
printf("\n");
x.u32 = ~x.u32;
for(size_t i=0; i<4; i++)
{
printf("%X ", x.u8[i]);
}
printf("\n");
}
Notably, the access order of the u8 is endianess dependent. This might be handy when dealing with something like RFID, which doesn't necessarily have the same network endianess as your MCU.

Creating AES-Key with C

How can I create an AES-Key using C? I like to create a pseudo-random 128-bit key using the rand function of C. I like to feed the rand function with a specific long number. I know that this is NOT secure and I know that I will get the same "random" number every time!
This is my code so far:
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t epoch = 1427863786;
printf("%d\n", rand((long)epoch));
}
Know I want to create the 128 bit key using the random number. How? Thanks!
You can even try something like this(assuming the fact that this is not secure is not bothering you):
unsigned char buf[16];
int i;
srand(time(NULL));
for (i = 0; i < sizeof(buf); i++) {
buf[i] = rand() % 256;
}
Since rand returns int(typical size 4 bytes), I doubt how in other way you can get 16 byte number using one call to rand.

c variable turning into -17918 when incremented

hi i am making a programming language that will run on the nintendo gameboy in c
which is why you will see some functions like waitpad();
but this question is unrelated the the gameboy librarys
for some reason when ever i try to increment a certain variable in my main.c file:
#include <stdio.h>
#include <gb/gb.h>
#include "convert.h"
#include "display.h"
#include "input.h"
#include "functions.h"
#include "interpreter.h"
unsigned char cnt[5] = {1,2,3,4,5};//cnt is short for counters
unsigned char k = 0;
unsigned char running = 1;
unsigned char memory[2048];
unsigned char code[2048];
int main()
{
Clear_mem();
Clear_code();
while(running == 1) {
display(cnt[0],cnt[1],cnt[2],cnt[3],cnt[4]);
printf("cnt[0] = %d\n", cnt[0]);
cnt[0]++;//turns into -17918
printf("Press Start To Enter Next Character\n");
waitpad(J_START);
code[k] = input();
interpret(code[k]);
k++;
}
return 0;
}
cnt[0] turns into -17918
can anyone see any problem that would cause it to behave this way?
You ask if anyone sees a problem, well - yes, here is a problem:
unsigned char k = 0;
unsigned char running = 1;
unsigned char code[2048];
while(running == 1) {
code[k] = input();
k++;
}
If k >= 2048, then code[k] = ... will cause a memory-override.
After a memory-override, pretty much anything can happens (undefined behavior).
Having said that, the value of k can be larger than 2047 only if CHAR_BIT is larger than 11.
Add #include <limits.h> to your program and make sure that CHAR_BIT is not larger than 11.
You have to convert it to an integer, because that's what you're trying to print:
printf("cnt[0] = %d\n", (int) cnt[0]);
When you're using a variadic function like printf, you have to make sure you're passing the right type. Check your compiler warning settings, new compilers can easily detect these kind of problems.
if you want to print the character value of your character variable you should print it like this:
printf("cnt[0] = %c\n", cnt[0]);
If you print it using %d the expansion of the character to a size of int could be negative for characters over half a character's size (0x80 and up).
If you insist on printing it as an int cast the variable like this:
printf("cnt[0] = %d\n", (int)cnt[0]);

converting data types in c

Let me start by saying that I openly admit this is for a homework assignment, but what I am asking is not related to the purpose of the assignment, just something I don't understand in C. This is just a very small part of a large program.
So my issue is, I have a set of data that consists various data types as follows:
[16 bit number][16 but number][16 bit number][char[234]][128 bit number]
where each block represents a variable from elsewhere in the program.
I need to send that data 8bytes at a time into a function that accepts uint32_t[2] as an input. How do I convert my 234byte char array into uint32_t without losing the char values?
In other words, I need to be able to convert back from the uint32_t version to the original char array later on. I know a char is 1byte, and the value can also be represented as a number in relation to its ascii value, but not sure how to convert between the two since some letters have a 3 digit ascii value and others have 2.
I tried to use sprintf to grab 8byte blocks from the data set, and store that value in a uint32_t[2] variable. It works, but then I lose the original char array because I can't figure out way to go back/undo it.
I know there has to be a relatively simple way to do this, i'm just lacking enough skill in C to make it happen.
Your question is very confusing, but I am guessing you are preparing some data structure for encryption by a function that requires 8 bytes or 2 uint32_t's.
You can convert a char array to uint32_t as follows
#define NELEM 234
char a[NELEM];
uint64_t b[(NELEM+sizeof(uint64_t)-1)/sizeof(uint64_t)]; // this rounds up to nearest modulo 4
memcpy(b,a,NELEM);
for(i .. ) {
encryption_thing(b[i]);
}
or
If you need to change endianess or something, that is more complicated.
#include <stdint.h>
void f(uint32_t a[2]) {}
int main() {
char data[234]; /* GCC can explicitly align with this: __attribute__ ((aligned (8))) */
int i = 0;
int stride = 8;
for (; i < 234 - stride; i += stride) {
f((uint32_t*)&data[i]); }
return 0; }
I need to send that data 8bytes at a time into a function that accepts
uint32_t[2] as an input. How do I convert my 234byte char array into
uint32_t without losing the char values?
you could use a union for this
typedef union
{
unsigned char arr[128]; // use unsigned char
uint32_t uints[16]; // 128/8
} myvaluetype;
myvaluetype value;
memcpy(value.arr, your_array, sizeof(value.arr));
say the prototype that you want to feed 2 uint32_t at a time is something like
foo(uint32_t* p);
you can now send the data 8 bytes at the time by
for (int i = 0; i < 16; i += 2)
{
foo(myvaluetype.uints + i);
}
then use the same struct to convert back.
of course some care must be taken about padding/alignment you also don't mention if it is sent over a network etc so there are other factors to consider.

Resources