So i have an array of bits, basically 0's and 1's in a character array.
Now what I want to do is store these bits in an integer I have in another array (int array), but I'm not sure how to do this.
Here is my code to get the bits:
char * convertStringToBits(char * string) {
int i;
int stringLength = strlen(string);
int mask = 0x80; /* 10000000 */
char *charArray;
charArray = malloc(8 * stringLength + 1);
if(charArray == NULL) {
printf("An error occured!\n");
return NULL; //error - cant use charArray
}
for(i = 0; i < stringLength; i++) {
mask = 0x80;
char c = string[i];
int x = 0;
while(mask > 0) {
char n = (c & mask) > 0;
printf("%d", n);
charArray[x++] = n;
mask >>= 1; /* move the bit down */
}
printf("\n");
}
return charArray;
}
This gets a series of bits in an array {1, 0, 1, 1, 0, 0, 1} for example. I want to store this in the integers that I have in another array. I've heard about integers having unused space or something.
For Reference: The integer values are red values from the rgb colour scheme.
EDIT:
To use this I would store this string in the integer values, later to be decoded the same way to retrieve the message (steganography).
So you want to do LSB substitution for the integers, the simplest form of steganography.
It isn't that integers have unused space, it's just that changing the LSB changes the value of an integer by 1, at most. So if you're looking at pixels, changing their value by 1 won't be noticeable by the human eye. In that respect, the LSB holds redundant information.
You've played with bitwise operations. You basically want to clear the last bit of an integer and substitute it with the value of one of your bits. Assuming your integers range between 0 and 255, you can do the following.
pixel = (pixel & 0xfe) | my_bit;
Edit: Based on the code snippet from the comments, you can achieve this like so.
int x;
for (x = 0; x < messageLength; x++) {
rgbPixels[x][0] = (rgbPixels[x][0] & 0xfe) | bitArray[x];
}
Decoding is much simpler, in that all you need to do is read the value of the LSB of each pixel. The question here is how will you know how many pixels to read? You have 3 options:
The decoder knows the message length in advance.
The message length is similarly hidden in some known location so that the decoder can extract it. For example, 16 bits representing in binary the message length, which is hidden in the first 16 pixels before bitArray.
You use an end-of-message marker, where you keep extracting bits until you hit a signature sequence that signals you to stop. For example, eight 0s in a row. You must make sure that how long the sequence and whatever it will be, it mustn't be encountered prematurely in your bit array.
So say somehow you have allocated the size for the message length. You can simply get extract your bit array (after allocation) like so.
int x;
for (x = 0; x < messageLength; x++) {
bitArray[x] = rgbPixels[x][0] & 0x01;
}
This converts a string to the equivalent int.
char string[] = "101010101";
int result = 0;
for (int i=0; i<strlen(string); i++)
result = (result<<1) | string[i]=='1';
Related
So I'm building a disassembler that will convert a file containing hexadecimal data into assembly language.
So from this format I could convert the hexadecimal data in the file into decimal using uint8_t and store them in an array. Then I decided to bit shift the last number in the array to get number of instructions of the last function; essentially I'm parsing backwards since I don't know how much padding there are at the beginning and the number of ops in a function is given at the end of the function. But then I realised that the operations varies in bit size and aren't in perfect 8 or 16 bit bounds. So then I was stuck since my array, using the example at the top, was essentially this:
uint8_t hex[] = {0x00, 0x03, 0x02, 0x01, 0x42, 0x82, 0x86, 0x04, 0x10, 0x45};
So can anyone help me with the logic in parsing? This is my first time posting so I'm sorry if I'm missing anything and will provide more information or delete if needed
Instead of shifting and masking (which I think would be really complicated) what if you convert the uint8_t array into an array of bits - it uses a lot more memory but you can access individual bits much easier.
Here is a sample program that does this:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
uint8_t getBits(uint8_t *bits, uint8_t size, uint32_t *index)
{
uint8_t value = 0;
*index -= size; // decrement index to the starting point
for(uint32_t i=0; i<size; i++)
value = (value<<1) | bits[*index+i];
return value;
}
int main()
{
// sample program
uint8_t array[] = {0x00,0x03,0x02,0x01,0x42,0x82,0x86,0x04,0x10,0x45};
// program with zero padding
// uint8_t array[] = {0xE8,0x39,0x06,0xA0,0xC4,0x16,0x82,0x90,0x4A,0x08,0x41};
uint32_t array_size = sizeof(array)/sizeof(*array); // 10 bytes
uint32_t bits_size = 8*array_size; // 80 bytes
uint8_t* bits = malloc(bits_size);
for(uint32_t a=0;a<array_size;a++)
for(uint32_t b=0;b<8;b++)
bits[a*8+b] = (array[a] >> (7-b)) & 1;
puts("Binary program file:");
for(uint32_t i=0;i<bits_size;i++)
printf("%s%d",(i%8?"":" "),bits[i]);
puts("");
enum { MOV, CAL, RET, REF, ADD, PRINT, NOT, EQU};
uint8_t params[] = { 2, 1, 0, 2, 2, 1, 1, 1};
const char *opcodes[] = {"MOV","CAL","RET","REF","ADD","PRINT","NOT","EQU"};
enum { VAL, REG, STK, PTR};
uint8_t value_size[] = { 8, 3, 5, 5};
const char *types[] = {"VAL","REG","STK","PTR"};
uint32_t index = bits_size; // start at end
// minimum program size is function(3) + opcode(3) + size(5)
// if there are less than that number of bits then it must be padding
while(index>10)
{
uint8_t size = getBits(bits,5,&index);
printf("\nsize=%d\n",size);
if (size > 0)
{
for(int o=0; o<size; o++)
{
uint8_t opcode = getBits(bits,3,&index);
printf("opcode=%s",opcodes[opcode]);
for(int p=0; p<params[opcode]; p++)
{
printf("%c ",p?',':':');
uint8_t type = getBits(bits,2,&index);
printf("type=%s ",types[type]);
uint8_t value = getBits(bits,value_size[type],&index);
printf("value=%d",value);
}
puts("");
}
uint8_t function = getBits(bits,3,&index);
printf("function=%d\n",function);
}
}
return 0;
}
Try it at https://onlinegdb.com/S1qVStz8d
How it getBits() works:
You make an array of individual digits from the original value, and then you take bits from it one at a time to make a new value - getBits() is the function I have written for that.
To understand how it works imagine how it works in base 10: 321 is put into the array {3,2,1} and you could turn it back into a value with:
value = 0;
value = value*10 + digits[0];
value = value*10 + digits[1];
value = value*10 + digits[2];
Which gives (((0)*10+3)*10+2)*10+1 which is 321
If 5 (binary 101) is put into the array {1,0,1}, you could turn it back into a value with:
value = 0;
value = value*2 + bits[0];
value = value*2 + bits[1];
value = value*2 + bits[2];
Which gives (((0)*2+1)*2+0)*2+1 which is 5 (binary 101)
And that does work. And a decent compiler would optimize the *2 into <<1 and the + into |, but you could do it yourself (which is what I did):
value = 0;
value = (value<<1) | bits[0];
value = (value<<1) | bits[1];
value = (value<<1) | bits[2];
Which produces that same binary 00000101
It's just a readability thing - with decimal you expect to see value*10+x but with binary you expect to see bit operations like shift/or instead of math operations like multiply/add.
Then, if you use a loop with a size and an index that points to the end of the array, you get:
uint8_t value = 0;
index -= size; // decrement index to the starting point
for(uint32_t i=0; i<size; i++)
value = (value<<1) | bits[index+i];
But, of course, if it is a function then index needs to be a pointer and you need to dereference it everywhere:
uint8_t getBits(uint8_t *bits, uint8_t size, uint32_t *index)
{
uint8_t value = 0;
*index -= size; // decrement index to the starting point
for(uint32_t i=0; i<size; i++)
value = (value<<1) | bits[*index+i];
return value;
}
How can I convert integer value to ASCII characters in C language?
I want to assign characters to array of chars.
char buff[10];
Let's say we have:
int = 93 (HEX: 5D) -> result should be - buff = {']'}
int = 13398 (HEX: 3456) -> result should be buff = {'4', 'V'}
Similar as is done here
I don't need to care about non printable characters. There will be always printable characters.
Just use bit-shifting to get the individual bytes.
Assuming an architecture on which the size of int is 4:
int someInt = ...
uint8_t first = (someInt >> 24);
uint8_t second = (someInt >> 16);
uint8_t third = (someInt >> 8);
uint8_t fourth = someInt;
Now you can just put the resulting bytes into your array. Make sure to check first, second and third to make sure they're not 0 first, and skip them if they are. Make sure to end your array with a null terminator, as required by C strings.
This answer assumes big-endian ordering, since that's what you indicated in your example. If you want little-endian, just reverse the order of the bytes when you put them in the array.
Note that this will turn 5DC into 05 and DC. If you want 5D instead, you should check to see whether the first digit in the original int is 0. You can do this using the & operator, testing the int against 0xf0000000, 0x00f00000, etc. If you find the first digit to be 0, shift the int to the right by 4 bits before extracting the bytes from it.
So, something like this:
void ExtractBytes(int anInt, uint8_t *buf, size_t bufSize) {
// passing an empty buffer to this function would be stupid,
// but hey, doesn't hurt to be idiot-proof
if (bufSize == 0) { return; }
// Get our sizes
const int intSize = sizeof(anInt);
const int digitCount = intSize * 2;
// find first non-zero digit
int firstNonZero = -1;
for (int i = 0; i < digitCount; i++) {
if ((anInt & (0xf << ((digitCount - 1 - i) * 4))) != 0) {
firstNonZero = i;
break;
}
}
if (firstNonZero < 0) {
// empty string; just bail out.
buf[0] = 0;
return;
}
// check whether first non-zero digit is even or odd;
// shift if it's odd
int intToUse = (firstNonZero % 2 != 0) ? (anInt >> 4) : anInt;
// now, just extract our bytes to the buffer
int bufPtr = 0;
for (int i = intSize - 1; i >= 0; i--) {
// shift over the appropriate amount, mask against 0xff
uint8_t byte = (intToUse >> (i * 8));
// If the byte is 0, we can just skip it
if (byte == 0) {
continue;
}
// always check to make sure we don't overflow our buffer.
// if we're on the last byte, make it a null terminator and bail.
if (bufPtr == bufSize - 1) {
buf[bufPtr] = 0;
return;
}
// Copy our byte into the buffer
buf[bufPtr++] = byte;
}
// Now, just terminate our string.
// We can be sure that bufPtr will be less than bufSize,
// since we checked for that in the loop. So:
buf[bufPtr] = 0;
// Aaaaaand we're done
}
Now let's take it for a spin:
uint8_t buf[10];
ExtractBytes(0x41424344, buf, 10);
printf("%s\n", buf);
ExtractBytes(0x4142434, buf, 10);
printf("%s\n", buf);
and the output:
ABCD
ABC
convert integer value to ASCII characters in C language?...
Referring to an ASCII table, the value of ']' in C will always be interpreted as 0x5D, or decimal value 93. While the value of "]" in C will always be interpreted as a NULL terminated char array, i.e., a string representation comprised of the values:
|93|\0|
(As illustrated in This Answer, similar interpretations are valid for all ASCII characters.)
To convert any of the integer (char) values to something that looks like a "]", you can use a string function to convert the char value to a string representation. For example all of these variations will perform that conversion:
char strChar[2] = {0};
sprintf(strChar, "%c", ']');
sprintf(strChar, "%c", 0x5D);
sprintf(strChar, "%c", 93);
and each produce the identical C string: "]".
I want to assign characters to array of chars...
example of how to create an array of char, terminated with a NULL char, such as "ABC...Z":
int i;
char strArray[27] = {0};
for(i=0;i<26;i++)
{
strArray[i] = i+'A';
}
strArray[i] = 0;
printf("Null terminated array of char: %s\n", strArray);
unsigned u = ...;
if (0x10 > u)
exit(EXIT_FAILURE);
while (0x10000 < u) u /= 2;
while (0x1000 > u) u *= 2;
char c[2] = {u / 0x100, u % 0x100);
Here I have created a string and I am storing the binary value of a number in the string.. I want to store the value of the variable num to the string.
i contains the length of the binary number for the given decimal number..suppose the given number is A=6, i contains 3 and i need a string 'result' having '110' which is the binary value of 6.
char* result = (char *)malloc((i)* sizeof(char));
i--;
while(A>=1)
{
num=A%2;
result[i]=num; // here I need to store the value of num in the string
A=A/2;
i--;
}
It appears from the code you've posted is that what you are trying to do is to print a number in binary in a fixed precision. Assuming that's what you want to do, something like
unsigned int mask = 1 << (i - 1);
unsigned int pos = 0;
while (mask != 0) {
result[pos] = (A & mask) == 0 ? '0' : '1';
++pos;
mask >>= 1;
}
result[pos] = 0; //If you need a null terminated string
edge cases left as an exercise for the reader.
I'm not sure specifically what you are asking for. Do you mean the binary representation (i.e. 00001000) of a number written into a string or converting the variable to a string (i.e. 8)? I'll assume you mean the first.
The easiest way to do this is to repeatedly test the least significant bit and shift the value to the right (>>). We can do this in for loop. However you will need to know how many bits you need to read. We can do this with sizeof.
int i = 15;
for (int b = 0; b < sizeof(i); ++b) {
uint8_t bit_value = (i & 0x1);
i >>= 1;
}
So how do we turn this iteration into a string? We need to construct the string in reverse. We know how many bits are needed, so we can create a string buffer accordingly with an extra byte for NULL termination.
char *buffer = calloc(sizeof(i) + 1, sizeof(char));
What this does is allocates memory that is sizeof(i) + 1 elements long where each element is sizeof(char), and then zero's each element. Now lets put the bits into the string.
for (int b = 0; b < sizeof(i); ++b) {
uint8_t bit_value = (i & 0x1);
size_t offset = sizeof(i) - 1 - b;
buffer[offset] = '0' + bit_value;
i >>= 1;
}
So what's happening here? In each pass we're calculating the offset in the buffer that we should be writing a value to, and then we're adding the ASCII value of 0 to bit_value as we write it into the buffer.
This code is untested and may have some issues, but that is left as an exercise to the reader. If you have any questions, let me know!
here is the whole code. It is supposed to work fine.
int i=0;
int A;//supposed entered by user
//calculating the value of i
while(A!=0)
{
A=A/2;
i++;
}
char* result=(char *)malloc(sizeof(char)*i);
i--;
while(A!=0)
{
result[i]='0'+(A%2);
A=A/2;
i--;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
char *numToBinStr(int num){
static char bin[sizeof(int) * CHAR_BIT + 1];
char *p = &bin[sizeof(int) * CHAR_BIT];//p point to end
unsigned A = (unsigned)num;
do {
*--p = '0' + (A & 1);
A >>= 1;
}while(A > 0);//do-while for case value of A is 0
return p;
}
int main(void){
printf("%s\n", numToBinStr(6));
//To duplicate, if necessary
//char *bin = strdup(numToBinStr(6));
char *result = numToBinStr(6);
char *bin = malloc(strlen(result) + 1);
strcpy(bin, result);
printf("%s\n", bin);
free(bin);
return 0;
}
You could use these functions in <stdlib.h>:
itoa(); or sprintf()
The second link has some examples as well.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a binary representation of a number as a char array which is at most 18 bits long. I need to store the three bits on the right, and the remaining bits into two different strings using bitwise operators.
For example, I have a char array containing "00000000011101". I need a function that will store "101" (the last three bits) and store "00000000011" (the remaining bits).
However, this must be done using bitwise operators. So I understand that I need to convert the strings to int, and then shift but I'm not sure how to go about this.
Your help would be very much appreciated.
Converting the string to int is easy: start with a zero int, then go through the characters of the binary representation, and check if it is zero or one. First, shift the partial result to the left. Then, if the digit is one, OR the result with 1. Continue to the next character. When you see null terminator '\0', stop.
Here is some pseudocode:
res = 0
ptr = "00000000011101"
while ptr is not pointing to '\0'
res <<= 1;
if ptr points to '1'
res |= 1;
Once you have your int, getting the last three bits is equivalent to AND-ing & the result with seven (its binary representation is 0000111). Getting the rest of the bits is equivalent to shifting >> the number right by three.
Here is some pseudocode:
lastThree = res & 7
topBits = res >> 3
You can always do it yourself. It's actually pretty simple.
int BitwiseOr(char str1[], char str2[]) //Although it probably works on not whole numbers too.
{
int i, output = 0;
char* outputstr = malloc(sizeof(char)(strlen(str1)>strlen(str2)?strlen(str1):strlen(str2))); //Although size of char is mostly 1. It's defined to fit to the biggest string size (binary representation there is).
char* rstr1;
char* rstr2;
if(strlen(str1)==strlen(str2)
{
rstr1 = str1; //Point to the same address.
rstr2 = str2; //As we are going to use these variables for cases if the strings' length aren't equal and we need to add zeros to the left.
}
else if(strlen(str1)>strlen(str2)
{
rstr1 = str1;
rstr2 = malloc(sizeof(char)*strlen(str1));
for(i = 0 ; i < strlen(str1)-strlen(str2) ; i++)
{
rstr2[i] = '0';
}
for(i = i /*To be one spot after the first loop was at*/ ; i < strlen(str1) ; i++)
{
rstr2[i] = str1[i];
}
}
else
{
rstr1 = malloc(sizeof(char)*strlen(str2));
rstr2 = str2;
for(i = 0 ; i < strlen(str2)-strlen(str1) ; i++)
{
rstr1[i] = '0';
}
for(i = i /*To be one spot after the first loop was at*/ ; i < strlen(str1) ; i++)
{
rstr1[i] = str1[i];
}
}
/*After memory is allocated*/
for(i = 0 ; i < strlen(outputstr) ; i++)
{
outputstr[i] = (str1[i]-'0') || (str2[i]-'0');
}
/*Now turn the number from binary string to decimal - pretty simple. Just go from the right to the left with powers of 2 when the first is 2 powered by zero and so on and when it's '1' in the output string - add to the output integer the 2 powered by the spot from the right*/
return output;
}
Some explanation of Bitwise Operators and uses and all.
Bitwise operators actually use the binary representation of a number and perform an action on it with another number. Example would be OR, as above. Takes all the bits, and just OR them all and get a number. What is it useful for? Actually tons of stuff. Working with graphics and colors especially, OpenGL uses them when setting a window, it defines constants and you send the Bitwise OR solution of them - and that way it knows all of the options you chose by knowing the possible option.
Here's a working C program to demonstrate a possible solution:
#include <stdio.h>
#include <string.h>
main()
{
int i;
unsigned int res = 0;
unsigned int bitmask = 1;
static unsigned char *ptr = "00000000011101";
printf("ptr = %s\n", ptr);
for (i=(strlen(ptr) -1); i>0; i--) {
printf("ptr[%d] = %c (bitmask = 0x%0x)\n", i, ptr[i], bitmask);
if (ptr[i] == '1')
res = (res | bitmask);
bitmask <<= 1;
}
printf("res = 0x%x\n", res);
}
I am trying to get my decoder code to work. I am using the example 64-bit encoded string from wikipedia, trying to reproduce the text they encoded.
#include <stdio.h>
//Convert raw binary character to the cb64 index
unsigned char get_cb64(unsigned char c){
if(c>='A' && c<='Z'){return c-'A';}
if(c>='a' && c<='z'){return c-'G';}
if(c>='0' && c<='9'){return c+4;}
if(c=='+'){return '>';}
if(c=='/'){return '?';}
else{return 0;}
}
void main(int argc, char** argv)
{
unsigned char* str = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=";
//convert each binary character to its cb64 index
int size = 360;
int num_bytes = 8;
unsigned char str_cb64[size + 1];
int cb64_idx;
int i;
for(i=0; i < size; i++){
str_cb64[i]=get_cb64(str[i]);
}
str_cb64[size] = 0;
//convert blocks of 4 6 bit chars to 3 8 bit chars
int end_size = size*6/8;
unsigned char ascii_out[end_size];
int out_idx = 0;
int in_idx = 0;
while(in_idx < end_size/4){
ascii_out[out_idx] = str_cb64[in_idx+0] << 2 | str_cb64[in_idx+1] >> 4;
ascii_out[out_idx+1] = str_cb64[in_idx+1] << 4 | str_cb64[in_idx+2] >> 2;
ascii_out[out_idx+2] = str_cb64[in_idx+2] << 6 | str_cb64[in_idx+3];
out_idx += 3;
in_idx += 4;
}
for(i=0; i < end_size; i++){printf("%d\n",ascii_out[i]);}
}
To inspect, the code here prints the ascii value of each decoded character, which SHOULD be between 48 and 122, but there are values from (0, 255). I tested the conversion from the raw binary to the cb64 index, and that seems to work fine. The problem is in my shifting code. Any idea why it isn't working? I double checked the shifts and they look like they are coded correctly.
Thanks!
Your loop should be either while(in_idx < size) or while(out_idx < end_size). Right now you are comparing an input value to an output value, as well as dividing the output value even though you add one for each byte instead of each iteration. This will cause your loop to exit well before all of the data has been processed. Since ascii_out wasn't initialized, this could be the only problem if the beginning of the output is right, since the end will contain random data which happened to be in that space.