What does this C code snippet mean? - c

I've come across this piece of code here.
result = HMAC(EVP_md5(), key, 32, data, 28, NULL, NULL);
for (i = 0; i < result_len; i++) {
sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
}
what does the loop do? In particular what does &(res_hexstring[i * 2]) mean? Can't you just iterate through result as an array? Why is it an integer?

It converts the hash result to a string:
e.g., from:
char result[2] = {0xa1, 0xb2};
to
char res_hexstring[4 + 1] = {'a', '1', 'b', '2', '\0'}
The expression i * 2 appears in &res_hexstring[i * 2] because the byte 0xa1 needs two characters ('a' and '1') to be represented in a string.
The advantage of having a string is it can be then easily displayed:
printf("%s\n", res_hexstring); // display the hash result

for (i = 0; i < result_len; i++) {
sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
}
sprintf prints the result from the binary array result 1 byte <=> 2 nibbles / hexadecimal digits at a time into the buffer res_hexstring.
Which is the reason the left index goes 2 byte for each 1 byte the second is moved.
Of course, not using sprintf would be much faster, but it would also need a bit more code.
(Which might result in a bigger or smaller binary, but that must be measured if of interest.)
inline char to16digit(int x) { return x<10 ? '0'+x : 'A'-10+x; }
for (i = 0; i < result_len; i++) {
res_hexstring[i*2] = to16digit(result[i]>>4);
res_hexstring[i*2+1] = to16digit(result[i]&15);
}
res_hexstring[2*result_len] = 0;
There are various reasons you might want it in a human-readable form, serializing, printing and logging prominent among them. (And printf does not have a format to print such big numbers in hexadecimal notation.)

Related

what's meant by converting an ASCII character to alphabetical index and how can i do that?

in Caesar (CS50) it says that i need to convert an ASCII character to alphabetical index in one of the steps. what does that mean? i saw a video that said that i "need to find the relationship between a number's ASCII value and its actual index in the alphabet", but i haven't really understood how I might implement this* and *what exactly is the relationship.
please elaborate in your answer because I'm new to this.
string plaintext = get_string("plaintext;");
As you may or may not know ASCII characters are encoded as 8-bit values and character constants, in reallity, have int type in C.
Using this knowledge you can perform character arithmetic as if they are regular numbers, take the following example:
printf("%d\n", 'a');
This prints 'a''s int value which is 97.
Now this:
printf("%d\n", 'g' - 'a');
This will print 6 which is the result of 103 - 97.
Now your string:
const char* plaintext = "plaintext";
for(size_t i = 0; i < strlen(plaintext); i++){
printf("%c - %d\n",plaintext[i], plaintext[i] - 'a' + 1);
}
The result:
p - 16
l - 12
a - 1
i - 9
n - 14
t - 20
e - 5
x - 24
t - 20
As you can see the printed results are the indexes of the letters in the alphabet 1...26, I added 1 to the result because, as you know, in C indexing starts at 0 and you would have 0...25.
So the bottom line is that you can use this character arithmetic to find the indexes of characters, this also aplies to caps, but you can't mix both.
Note that there are other character encodings that do not allow for this kind of arithmetic because the alphabetic characters are not in sequencial order, like, for example, EBCDIC.
It means that a single char variable is nothing but an integer containing an ASCII code, such as 65 for 'A'. It might be more convenient for an algorithm to work with the interval 0 to 25 than 65 to 90.
Generally, if you know that a char is an upper-case letter, you can do a naive conversion to alphabetical index by subtracting the letter 'A' from it. Naive, because strictly speaking the letters in the symbol (ASCII) table need not be located adjacently. For a beginner-level program, it should be ok though:
char str[] = "ABC";
for(int i=0; i<3; i++)
printf("%d ", str[i] - 'A'); // prints 0 1 2
Wheras a 100% portable converter function might look something like this:
int ascii_to_int (char ch)
{
const char LOOKUP_TABLE [128] =
{
['A'] = 0,
['B'] = 1,
...
};
return LOOKUP_TABLE[ch];
}
Here you have an example. It is portable as it does not depend if the char encoding.
const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
int getIndex(const char *alphabet, int c)
{
int result = -1;
const char *res;
res = strchr(alphabet, c);
if(res)
{
result = res - alphabet;
}
return result;
}
int main(void)
{
char *str = "Hello World!!!";
while(*str)
{
printf("Index of %c is %d\n", *str, getIndex(alphabet, *str));
str++;
}
}
https://godbolt.org/z/rw2PK9

Program to convert octal to binary number system

i am a beginner in c programing language and in this few days i'm train to do some c exercises
and i get stucked in some exercice for conversions:
so this is what i had did
#include <stdio.h>
#include <string.h>
int main() {
int num[8] = {
0,
1,
2,
3,
4,
5,
6,
7
};
long long binary, octal, tempoctal;
int last, i, A, tempi;
char hex[9] = {
'000',
'001',
'010',
'011',
'100',
'101',
'110',
'111'
};
int bex[10];
A = 0;
printf("enter an octal number: ");
scanf("%lld", & octal);
tempoctal = octal;
while (tempoctal != 0) {
last = tempoctal % 10;
for (i = 0; i < 8; i++) {
if (num[i] == last) {
tempi = i;
bex[A] = tempi;
}
}
A++;
tempoctal /= 10;
}
printf("\nthe is %s", bex);
return 0;
}
so i want just to know why when i want to print the array of bex
i get error on the consol enter image description here.
Although i know the solution but i want to do it in my own way.
Answering your question. bex is declared as int bex[10], array of integers. printf("%s"... expects a character string, not an array of int.
A character string is usually an array of chars char bex[10]. Char is a single byte, and an int is usually 4-byte long. So, you see the difference there. In your example you modify the lowest byte of the 'int', leaving other 3 as '0'.
printable chars have corresponding codes. For example a char of '0' has code of 48 in asccii encoding. All other chars that represent numbers have consecutive codes (48..57). This how the printf and other services know what to print if they see 48 in the byte.
the string in 'c' ends with a stray 0, so that the printf knows where to stop reading the chars.
So, if you want to print 'bex' as a string, you need to create it as a string. for example
char bex[10];
for (i=0; i <8; i++)
bex[A++] = '0' + i; // code of '0' + a number
bex[A] = 0; // string terminator
Just make sure that your 'A' is always less than '8' to avoid array overflow (string length of 9 plus one character for the terminator. Now you can do this.
printf("%s", bex);
You have to work on the rest of the program, because it does not do anything useful in the current state, but this should help you to get going.

Replace a subarray with a character in C

I have an array and I need to replace a subarray from this array with a character.
unsigned char * data = {'a','b','c','d','e'};
I need to delete 'a','b''c' and insert 'R'
The final array will be: unsigned char * data = {'R','d','e'};
With only 3 elements.
How can I do that in C?
You say you think of data as an array, therefore it is better that you declare data as an array instead of a pointer. (The way your code is now you have a pointer that is initialized incorrectly by casting the character 'a' to a char * pointer. That way it will not be pointing anywhere.)
You can replace characters by assigning to elements of the array, and you can shift parts of the data in the array using memmove.
Which means that maybe you want something like this:
unsigned char data[] = {'a','b','c','d','e'};
data[0] = 'R';
memmove(data + 1, data + 3, sizeof(data) - 3);
The memmove call moves sizeof(data) - 3 bytes of data from address data + 3 to address data + 1. The function memmove even works when the regions of memory between which you are moving bytes of data overlap.
If you then print the relevant part of your data:
fwrite(data, 1, sizeof(data) - 2, stdout);
putchar('\n');
This will get you the output:
Rde
However, notice that the size of the array will not have changed. It still will be five characters long. So replacing abc by something longer than three characters will not work like this. Also, this array is not a null-terminated string, which is the more usual way to have sequences of characters in C.
If you prefer to use a string "abcde" instead of what you are doing now (but then why call it "data"?), add a comment below this answer, and I'll extend it.
for(int i = 0; i < 5; i++){
if (data[i] > 96 && data[i] < 100) data[i] = 'R';
}
How about the following way?
unsigned char * data = {'a','b','c','d','e'};
int length = strlen(data);
unsigned char * output = (unsigned char *)malloc(sizeof(unsigned char)*length);
for(int i = 0, j =0; i < length; i++, j++){
if (i+2 < length && data[i] == 'a' && data[i+1] == 'b && data[i+2] == 'c') {
output[j]='R';
i++;
i++;
}
else
output[j]=data[i];
}

Binary to UTF-8 in C

I am working on an application in C where I need to show Unicode UTF-8 characters. I am getting the values as a binary byte stream as 11010000 10100100 as character array which is the Unicode character "Ф".
I want to store and display the character. I tried to convert the binary to a hexadecimal character array. But printing with
void binaryToHex(char *bData) {
char hexaDecimal[MAX];
int temp;
long int i = 0, j = 0;
while (bData[i]) {
bData[i] = bData[i] - 48;
++i;
}
--i;
while (i - 2 >= 0) {
temp = bData[i - 3] * 8 + bData[i - 2] * 4 + bData[i - 1] * 2 + bData[i];
if (temp > 9)
hexaDecimal[j++] = temp + 55;
else
hexaDecimal[j++] = temp + 48;
i = i - 4;
}
if (i == 1)
hexaDecimal[j] = bData[i - 1] * 2 + bData[i] + 48;
else if (i == 0)
hexaDecimal[j] = bData[i] + 48;
else
--j;
printf("Equivalent hexadecimal value: ");
char hexVal[MAX];
// size_t len = j+1;
int k = 0;;
while (j >= 0) {
char *ch = (char*)hexaDecimal[j--];
if (j % 2 == 0) {
hexVal[k] = '\\';
k++;
hexVal[k] = 'x';
k++;
}
printf("\nkk++Length %d ...J= %d.. ", k, j);
hexVal[k] = ch;
k++;
printf("%c", ch);
}
printf("KKKK+=== %d", k);
hexVal[k] = NULL;
// printf("\nkk++Length %d",strlen(hexVal));
printf("\nMM+-+MM %s===\n ..>>>>", hexVal);
}
Only showing the value as \xD0\xA4. I did string manipulation for that.
But when writing in the way
char s[]= "\xD0\xA4";
OR
char *s= "\xD0\xA4";
printf("\n %s",s);
producing the desired result that is printing the character "Ф". How can I get the correct string dynamically? Is there any library for this in C?
The code is from http://www.cquestions.com/2011/07/binary-to-hexadecimal-conversion-in.html.
Is there a way to print it from binary directly or from a HEX value. Or is there an alternative for that?
Escape codes such as \xD0 are interpreted by the compiler when encountered in the value of a character or string literal. The compiler replaces them with the corresponding byte (or byte sequence in some cases). They are not meaningful to C at runtime.
You are therefore not only making it harder on yourself but doing altogether the wrong thing by constructing and printing the text of such escape sequences at runtime. What you get is exactly what you should expect. Just print the literal byte sequence you decode from the program input, without any dress-up.
At last converting the Unicode binary char array to actual binary codepoint like converting
11010000 10100100 to 10000 100100 and then converting to decimal and then to Unicode solved my problem for now.below is the link I use to convert to UTF8 from decimal.
C++ Windows decimal to UTF-8 Character Conversion
resources I used:
https://www.youtube.com/watch?v=vLBtrd9Ar28
http://www.zehnet.de/2005/02/12/unicode-utf-8-tutorial/

Storing bits from an array in an integer

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';

Resources