Convert hexadecimal value (ASCII) to text - c

I am trying to convert ASCII hexadecimal value (0x61 or 61) to it's char value (61 = a, etc..) without atoi, scanf, strcat.
I am saving getchar() to temp variable, then I save first one (6) in array, then save second one (1) in array, now i want take these two and convert them to their ASCII value.
68656c6c6f0d0a = hello
void asd(char fde)
{
char asmg[3];
asmg[0] = "0x";
asmg[1] = "6";
asmg[2] = "1";
printf("%c", asmg);
}
I expected it to print "a", but it doesn't work.
Something like that, but this doesn't work. I need to put asmg[0], [1], [2] to one char, then it should work.
Thanks :)

Not sure exactly what you are trying to do but this may help.
int main(int argc, char **argv)
{
int hex[6] = {0x68, 0x65, 0x6C, 0x6C, 0x6F};
int i = 0;
for(i = 0; i <6; i++)
{
printf("%c", hex[i]);
}
printf("\n");
}

#include <stdio.h>
int main(void){
char hex[] = "68656c6c6f0d0a";
char text[(sizeof(hex)+1)/2];
int i = 0, j = 0;
while(hex[i]){
int up = '0' <= hex[i] && hex[i] <= '9' ? hex[i] - '0' : hex[i] - 'a' + 10;//lowcase
if(hex[++i] == '\0'){
printf("invalid format\n");
return -1;
}
int low = '0' <= hex[i] && hex[i] <= '9' ? hex[i] - '0' : hex[i] - 'a' + 10;//lowcase
text[j++] = up * 16 + low;
++i;
}
text[j] = 0;
printf("%s", text);
return 0;
}

you can use this function to convert Hexastring to ASCII
void hexToAscii(unsigned char *buf, int size, char *str) {
int i;
for (i = 0; i < size; ++i) {
sprintf(str + (i * 2), "%02X", buf[i]);
}
}
Don't for get to set the last element on the string to null.

Related

Convert string of lower case to upper case? In C

My professor gave me some exercises in C language... In one of them I have to pass a string as an argument to a function, this function will verify the existence of lower case letters in the array and convert it into upper case letter;
Actually there's a function to do such a thing, but I can't use string.h.
Does anyone have an idea to do it?
void converterup(char palavra[])
{
int i;
for(i = 0; i < 10; i++)
{
if(palavra[i] != 'a')
{
palavra[i] == 'A';
}
}
Would be something like this?
you need to include <ctype.h> before using function toupper, then use it like in example below (I edited your code, need to adjust it for your needs):
for(i = 0; i < 10; i++){
palavra[i] = toupper(palavra[i]);
}
this loop will convert 10 first characters to their upper ascii equivalents
or if you cannot use standard functions, you can use function like this:
char myUpperChar(char x){
const int delta = 'a' - 'A'; //'a' has ascii code 97 while 'A' has code 65
if(x <= 'z' && x >= 'a'){
x -= delta;
}
return x;
}
If a character is between 'a' and 'z', you could just add ('A' - 'a') to it to convert it to upper.
char input, output;
int diff = 'A' - 'a';
output = input;
if ('a' <= input && input <= 'z')
output += diff;
return output;
I guess your professor is expecting something more basic without external functions, like this.
char str[] = "hello";
int len = sizeof(str) / sizeof(char);
int i;
for(i = 0; i < len; i++) {
int ascii = str[i];
if(ascii >= 97 && ascii <= 122) {// 97 => 'a' and 122 => 'z' in ascii
str[i] = (char) (ascii - 32); // 32 is the ascii substraction of lower
} // and upper letters 'a' - 'A'
}
Then output would be:
HELLO
function will verify the existence of lower case letters in the
array and convert it into upper case letter;
I can't use string.h.
Then you have to do conversion yourself. Take a look at the ASCII chart.
Then you can notice that small and capital letters are 0x40 apart.
0x40 happens to be space ' ';
Loop through your array and convert only the small letters
arr[i] <= 'z' && arr[i] >= 'a'
remember that small and capital letters are ' ' apart.
arr[i] = arr[i] - ' ' ;
advance to next character in the array by increasing the index i++ and stop when you encounter the end of the string arr[i]=='\0'.
#include <stdio.h>
void converterup(char arr[])
{
size_t i = 0;
if(arr == NULL) return;
while(arr[i]) // loop till the '\0'; this is equivalent to `arr[i]!='\0'`
{
if(arr[i] <= 'z' && arr[i] >= 'a'){
arr[i] = arr[i] - ' ' ;
}
i++;
}
}
int main(void)
{
char str[] = "Hello World!";
converterup(str);
printf("%s",str);
return 0;
}
Test:
HELLO WORLD!
Check out my code guys, is it acceptable?
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
void strupr(char palavra[])
{
int i;
for(i = 0;palavra[i] > 60 && palavra[i] < 122; i++)
{
printf("%c", palavra[i] - 32);
}
}
int main(void)
{
setlocale(LC_ALL, "");
char palavra[10];
printf("Insira uma palavra maiúsculas: "); gets(palavra);
printf("Valor com conversão: ");
strupr(palavra);
return 0;
}

How to convert Hex char into bytes like \x90\x90?

I am searching a way to convert hex char to bytes like \x90\x0d\x41 and when I use printf(), binary data are printed?
char *hex = "909090904241";
when I need to get \x90\x90\x90\x90\x42\x42 and when I print I get binary data.
int hex_to_bytes(const char* hex, uint8_t** buf_ptr, size_t** len_ptr) {
size_t len = strlen(hex);
if (len % 2)
goto error1;
len /= 2;
char* buf = malloc(len);
char hex_byte[3];
hex_byte[2] = 0;
for (size_t i=len; i--; ) {
hex_byte[0] = *(hex++);
hex_byte[1] = *(hex++);
char* end_ptr;
buf[i] = strtoul(hex_byte, &end_ptr, 16);
if (end_ptr != hex_byte+2)
goto error2;
}
*buf_ptr = buf;
*len_ptr = len;
return 1;
error2:
free(buf);
error1:
*buf_ptr = NULL;
*len_ptr = 0;
return 0;
}
uint8_t* buf;
size_t len;
if (!hex_to_bytes(hex, &buf, &len)) {
... handle error ...
}
... Use buf and len ...
free(buf);
Notes that buf isn't nul-terminated. I didn't see the point of making it nul-terminated string when the input could be "000000".
For each character in the string, first convert it to a number by subtracting its ASCII by either the character '0' or 'A'. Then assign each value into the target array, shifting as necessary.
The below assumes ASCII, and that the input string contains only characters in the range 0-9 and A-F.
char *str="909090904241";
unsigned char a[strlen(str)/2+1] = {0};
int i;
for (i=0;i<strlen(str);i++) {
unsigned char num = (str[i] >= '0' && str[i] <= '9') ? str[i] - '0' : str[i] - 'A' + 10;
a[i/2] |= num << (4 * (1 - (i % 2))); // shift even index bits by 4, odd index by 0
}
for (i=0;i<strlen(str)/2+1;i++) {
printf("%02x ", a[i]);
}
printf("\n");
Output:
90 90 90 90 42 41
so basically I have a variable which contains hex bytes and when I print them I obtain binary representation
#include<stdio.h>
char *hex_bytes = "\x90\x90\x90\x41";
int main () {
printf(hex_bytes);
return 0 ;
}
I wanna do the same with hex chars like that
char *hex = "9090904241";
Thank you , HM
Loop through the string and append to a new string a piece with \x added infront like this:
const char *hex = "909090904241";
char* result = malloc((strlen(hex) * 2 + 1)* sizeof(char));
result[0] = 0;
char piece[] = "\\x00";
for (int i = 0; i < strlen(hex); i+=2) {
piece[2] = hex[i];
piece[3] = hex[i+1];
strcat(result, piece);
}

Merging two index into one in array in C

I have an unsigned char array which contains hex bytes like below:
unsigned char array[255];
array[0] = 'F';
array[1] = 'F';
array[2] = 'E';
array[3] = '2';
array[4] = 'A';
array[5] = 'A';
array[6] = 'C';
array[7] = 'C';
I want to merge them so that it becomes:
array[0] = "FF"
array[1] = "E2"
array[2] = "AA"
array[3] = "CC"
array[0] = '\xFF';
array[1] = '\xE2';
array[2] = '\xAA';
array[3] = '\xCC';
I have tried using sprintf but then I do not know how to specify index number in it. Any help.?
So, you want to convert your string, made of hexadecimal characters, into an array of bytes, right? Know your data.
sprintf() will not help you, since it produces strings. Instead, you will need to extract the 'value' of each hexa character and use it to calculate the value of your bytes.
So, let's create a helper function to convert a hexadecimal character to its integer value (or -1 if it is invalid). We will use the characters' ASCII values and the fact that character ranges are contiguous in the ASCII table
int char2hexa(unsigned char c)
{
if(c >= '0' && c <= '9') {
return (c - '0'); /* will return 0-9 */
} else if(c >= 'A' && c <= 'F') {
return (c - 'A') + 10; /* will return 10-15 */
} else if(c >= 'a' && c <= 'f') {
return (c - 'a') + 10; /* will return 10-15 */
} else {
return -1;
}
}
Now a byte will be constructed from two hexa values by using one as the upper nibble (multiplied by 16 or shifted left by 4) and the other as a lower nibble, so let's have a function for that:
unsigned char hexvals2byte(int upper, int lower)
{
return (upper * 16 + lower);
}
and put the pieces together. I will assume that:
you know the length of your input data
the length is even (you need two characters per byte)
you want to put the result in the same array
Here comes.
#include <stdio.h>
#include <stdlib.h>
unsigned char array[255];
array[0] = 'F';
array[1] = 'F';
array[2] = 'E';
array[3] = '2';
array[4] = 'A';
array[5] = 'A';
array[6] = 'C';
array[7] = 'C';
unsigned length = 8;
int upper, lower;
for(int i = 0; i < length; i+=2) {
upper = char2hexa(array[i]);
lower = char2hexa(array[i+1]);
if(upper < 0 || lower < 0) {
/* handle input data format error */
fprintf(stderr, "ERROR: Cannot decode hexa values '%c%c'\n", array[i], array[i+1]);
exit(EXIT_FAILURE);
}
array[i/2] = hexvals2byte(upper, lower);
}
So you need a result array of unsigned char result[128][3], then assign the part results, grouping 2 source elements into one result sub-element:
unsigned char result[128][3] = { 0 };
int i;
for (i = 0; i < 255; ++i)
{
result[i/2][i%2] = array[i];
}
The reason for size 3 is, that you need 2 characters and one zero-delimiter to form a string.
An easy way to convert a digit to number is to subtract '0' from it:
char digit = '3';
int number = digit - '0'; /* number = 3 */
This works only for digits (digit >= '0' && digit <= '9'), for hexadecimal digits ('A', 'B', etc.) you have to do a little more job:
unsigned char result[127];
int i;
unsigned char current;
unsigned char calc_diff(unsigned char digit) {
if(digit >= '0' && digit <= '9')
return '0';
else if(digit >= 'A' && digit <= 'F')
return 'A' - 10;
else if(digit >= 'a' && digit <= 'f')
return 'a' - 10;
else
return 0; // handle invalid digit
}
for(i = 0; i < 128; ++i) {
current = array[2 * i];
result[i] = (current - calc_diff(current)) << 4;
current = array[(2 * i) + 1];
result[i] |= current - calc_diff(current);
}
You want to convert characters to their hexadecimal value and combine them in pairs.
Here is a simple program to illustrate how you can do this:
#include <stdio.h>
#include <string.h>
static int xdigit(unsigned char c) {
/* this method is inefficient but works for all encodings */
static const char xdigits[] = "abcdef0123456789ABCDEF";
const char *p = memchr(xdigits, c, 22);
return p ? (p - xdigits + 10) & 15 : -1;
}
int main(void) {
unsigned char array[255];
while (scanf("%254s", array) == 1) {
int i, j, d, d2 = 0;
for (i = j = 0; array[i] != '\0'; i++) {
d = xdigit(array[i]);
if (d < 0) {
printf("invalid hexadecimal digit: %c\n", array[i]);
break;
}
d2 = (d2 << 4) | d;
if (i & 1) {
array[j++] = (unsigned char)d2;
d2 = 0;
}
}
array[j] = '\0';
printf("converted array: %s\n", array);
}
return 0;
}
Here is a more elaborate version, with an separate conversion function and more explicit output:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static int xdigit(unsigned char c) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return c - '0';
case 'A': case 'a':
return 10;
case 'B': case 'b':
return 11;
case 'C': case 'c':
return 12;
case 'D': case 'd':
return 13;
case 'E': case 'e':
return 14;
case 'F': case 'f':
return 15;
default:
return -1;
}
}
int xconvert(unsigned char *dest, const unsigned char *src, int len) {
int i, j, d, d2 = 0;
for (i = j = 0; i < len; i++) {
d = xdigit(src[i]);
if (d < 0) {
printf("invalid hexadecimal digit: %c\n", src[i]);
return -1;
}
d2 = (d2 << 4) | d;
if (i & 1) {
dest[j++] = (unsigned char)d2;
d2 = 0;
}
}
if (i & 1) {
printf("missing trailing digit\n");
return -1;
}
return j;
}
int main(void) {
unsigned char array[255];
int i, len, c;
while (scanf("%254s", array) == 1) {
len = xconvert(array, array, strlen((char *)array));
if (len >= 0) {
printf("converted array: \"");
for (i = 0; i < len; i++) {
c = array[i];
if (isprint(c)) {
putchar(c);
} else {
printf("\\x%02X", c);
}
}
printf("\"\n");
}
}
return 0;
}
my stab at it. Here you have to know the size of the array. in your case 255
//counters and array's
int first = 0;
int second = 0;
int count = 0;
char foo[8] = {'F', 'F', 'E', '2', 'A', 'A', 'C', 'C'};
//array half the size of the first one.
char *done[4];
//loop through first array
while (first <= 7)
{
//if its the first letter
if (second == 0)
{
//allocate enough mem to second arr
done[count] = (char *)malloc(sizeof(char *) * 3);
//assaign the first letter
done[count][0] = foo[first];
//indicate the next step for the second letter
second = 1;
}
//if its the second letter
else if (second == 1)
{
//assign second letter
done[count][1] = foo[first];
//null the string
done[count][2] = '\0';
//increase posistion index for the second arr
count++;
//indicate nexxt step is a the first letter of the next step
second = 0;
}
//increment the index for the first arr
first++;
}
Given that the data is in ASCII format and you want to merge it into a raw binary format, then:
for(size_t i=0; i<n; i++)
{
array[i] = to_int(array[i]);
}
where to_int() is your custom routine for converting from hexadecimal ASCII to integer. That is, if digit subtract with '0', else if upper-case letter subtract with 'A' and add 0xA.
Then after that, merge the items:
for(size_t i=0; i<n; i+=2)
{
array[i] = (unsigned int)array[i]<<4 | array[i+1];
}
I suppose you mix up an 8 bit value (e.g. 0x0F, which is 15 in decimal) with a character value like 'F' (which corresponds to 70 in ASCII format) with a string literal "FF" (which corresponds to a pointer to a sequence of the three character values {'F','F','\0'}.
From the context you present it seems that you mean 8 bit values, which are represented by data type unsigned char.
Given that, the code could look as follows:
unsigned char array[255] = { 0xF,0xE,0x2,0xA,0xA,0xC,0xC };
int target=0;
for (int i=0; i<254; i+=2) {
array[target] = (array[i] << 4) + array[i+1];
target++;
}
Maybe there are uncertain things but perhaps you want to do this.
#include <stdio.h>
int main(void){
unsigned char array[255] = {//or char -> hex byte
'\xF', '\xF', '\xE', '\x2',
'\xA', '\xA', '\xC', '\xC',
};
int len = 8;
for(int i = 0, j = 0; i < len; i += 2){
array[j++] = (array[i] << 4) | array[i+1];
}
len = len / 2;
for(int i = 0; i < len; i++){
printf("%02hhX", array[i]);//FFE2AACC
}
printf("\n");
}
When the data held first is a hex character
#include <stdio.h>
#include <ctype.h>
int main(void){
unsigned char array[255] = {
'F', 'F', 'E', '2',
'A', 'A', 'C', 'C',
};
int len = 8;
for(int i = 0, j = 0; i < len; i++){
if(isxdigit(array[i])){//maybe redundant
if(isdigit(array[i])){
array[i] -= '0';
} else {
array[i] -= isupper(array[i]) ? 'A' : 'a';
array[i] += 10;
}
} else {
fprintf(stderr, "invalid data %c\n", array[i]);
return -1;
}
}
for(int i = 0, j = 0; i < len; i += 2){
array[j++] = (array[i] << 4) | array[i+1];
}
len = len / 2;
for(int i = 0; i < len; i++){
printf("%02hhX", array[i]);
}
printf("\n");
}

I cannot add an offset to a char array, and is my method of receiving strings and ints from the command line optimal?

In the first for loop I am trying to add an offset to a char array and am not able to do so.
I also wanted input from the terminal so I wrote code that is a ** to argv[2] and used atoi() to convert a char from argv[1] to an int.
int main(int argc, char *argv[]) {
if(argc != 3) {
printf("Enter an integer followed by a string \n\n");
return 1;
}
int i;
int offset = atoi(argv[1]);
char **p_message;
p_message = &argv[2];
char encrypt[strlen(*p_message)];
printf("You Entered: %d, %s \n", offset, *p_message);
for(i = 0; i < strlen(*p_message); i++)
{
encrypt[i] = ((*p_message[i] + offset) % 26);
}
for(i = 0; i < strlen(*p_message); i++)
{
printf("%c", encrypt[i]);
}
return 0;
}
The main problem is that you are not making an alphabet adjustment before, and after, the modulus operation. I added the variable letter as an int so that the arithmetic won't overflow.
You could simplify the program by dropping one of the stars for **p_message. Also, you would normally allocate an array 1 longer than the string, to allow for a nul terminator, but here, you are not treating the char array as a string, so no need.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if(argc != 3) {
printf("Enter an integer followed by a string \n\n");
return 1;
}
int i;
int offset = atoi(argv[1]);
char *p_message; // remove a *
p_message = argv[2]; // remove &
char encrypt[strlen(p_message)]; // remove *
int letter; // added
printf("You Entered: %d, %s \n", offset, p_message); // remove *
for(i = 0; i < strlen(p_message); i++) { // remove *
letter = p_message[i]; // remove *
if(letter >= 'a' && letter <= 'z') { // if lower case
letter = 'a' + ((letter - 'a') + offset) % 26;
}
else if(letter >= 'A' && letter <= 'Z') { // if upper case
letter = 'A' + ((letter - 'A') + offset) % 26;
}
encrypt[i] = letter;
}
for(i = 0; i < strlen(p_message); i++) { // remove *
printf("%c", encrypt[i]);
}
return 0;
}

C code to convert hex to int

I am writing this code to convert a hex entry into its integer equivalent. So A would be 10 and B would be 11 etc. This code acts weirdly, in that it seg. faults at random locations and including an extra newline character at times will get it to work. I am trying to debug it, just so I can understand what I am doing wrong here. Can anyone take a look and help me here ? Thanks a lot for your time.
/* Fixed working code for anyone interested */
#include <stdio.h>
#include <stdlib.h>
unsigned int hextoint(const char temp[])
{
int i;
int answer = 0;
int dec;
char hexchar[] = "aAbBcCdDeEfF" ;
for ( i=0; temp[i] != '\0'; i++ )
{
if ( temp[i] == '\0')
{
return ;
}
if (temp[i] == '0' || temp[i] == 'x' || temp[i] == 'X' )
{
printf("0");
answer = temp[i];
}
// compare each temp[i] with all contents in hexchar[]
int j;
int a = temp[i];
for ( j=0; hexchar[j] != '\0'; j++)
{
if ( temp[i] == hexchar[j] )
{
answer *= 16;
answer = answer + 10 + (j/2);
// printf("%d\n",answer );
break;
}
}
}
return answer;
}
main()
{
char *test[] =
{ "bad",
"aabbdd"
"0100",
"0x1",
"0XA",
"0X0C0BE",
"abcdef",
"123456",
"0x123456",
"deadbeef",
"zog_c"
};
int answer=0;
// Calculate the number of char's.
int numberOfChars;
numberOfChars = sizeof test /sizeof test[0];
printf("main():Number of chars = %d\n",numberOfChars);
int i;
// Go through each character and convert Hex to Integers.
for ( i = 0; i<numberOfChars;i++)
{
// Need to take the first char and then go through it and convert
it.
answer = hextoint(test[i]);
printf("%d\n",answer );
}
}
Let's take a look.
unsigned int hextoint(const char temp[])
{
int i;
int answer = 0;
char hexchar[] = "aAbBcCdDeEfF" ;
for ( i=0; temp[i] != '\0'; i++ )
{
printf("In here");
printf("%c\t",temp[i] );
}
return answer;
}
This doesn't seem to even try to do any conversion. It should always return 0, since answer is never assigned any other value. Normally, you'd do something like:
for (i=0; input[i] != '\0'; i++) {
answer *= 16;
answer += digit_value(input[i]);
}
return answer;
Where digit_value (obviously enough) returns the value of an individual digit. One way to do this is:
int digit_value(char input) {
input = tolower(input);
if (input >= '0' && input <= '9')
return input - '0';
if (input >= 'a' && input <= 'f')
return input - 'a' + 10;
return -1; // signal error.
}
Then, looking at main:
main()
{
Depending on the "implicit int" rule is generally poor practice, at least IMO. It's much better to specify the return type.
// Calculate the number of char's.
int numberOfChars;
numberOfChars = sizeof test /sizeof test[0];
This actually calculates the number of strings, not the number of chars.
for ( i = 0; i<=numberOfChars;i++)
Valid subscripts run from 0 through the number of items - 1, so this attempts to read past the end of the array (giving undefined behavior).
This'll work for any number within the unsigned int range, the nice thing is it does not use any other library functions so it is great for micro-controllers where space is tight.
unsigned int hexToInt(const char *hex)
{
unsigned int result = 0;
while (*hex)
{
if (*hex > 47 && *hex < 58)
result += (*hex - 48);
else if (*hex > 64 && *hex < 71)
result += (*hex - 55);
else if (*hex > 96 && *hex < 103)
result += (*hex - 87);
if (*++hex)
result <<= 4;
}
return result;
}
The problem is with calculating numberOfChars part. sizeof test is actually the size of the pointer, not the total length of all characters in your array, so the number returned in your code would be 1, which makes the for loop go to the second index of test (test[1]) which does not have a \0 at the end. Try using strlen for calculating numberOfChars.
This may not me the most optimal method, but it should work without problem.
unsigned int hex_to_int(const char* hex) {
unsigned int result = 0;
size_t len = strlen(hex);
for (size_t i = 0; i < len; ++i) {
char cur_char = tolower(hex[len - i - 1]);
// direct return if encounter any non-hex character.
if (!(isdigit(cur_char) && (cur_char >= 'a' && cur_char <= 'f'));)
return result;
unsigned int char_val = (isdigit(cur_char) ? cur_char - '0' : 10 + cur_char - 'a');
result += round(pow(16, i)) * char_val;
}
return result;
}

Resources