Increase Char value by one - c

I have the following code:
char buf[] = {0x45, 0x76, 0x72, 0x23, 0x12};
int main(void)
{
int i;
for (i = 0; i<=sizeof(buf); ++i){
printf("%c\n", buf[i]);
}
}
What I want to do is take buf[i] when it is printed out and and make 0x45 read 0x46. Essentially, how do I add 1 to each value as it is going through the for loop?

Use +
for (i = 0; i<sizeof(buf); ++i){
printf("%c\n", buf[i] + 1); // print the incremented value
//printf("%c\n", buf[i]++); // increment the printed value
}

You add 1 to it:
#include <stdio.h>
char buf[] = { 0x45, 0x76, 0x72, 0x23, 0x12 };
int main(void)
{
int i;
for (i = 0; i < sizeof(buf); i++)
printf("%c\n", buf[i] + 1);
}
As simple as that!
If you want the value in the buffer changed as well as printed, then you probably use ++buf[i] in place of buf[i] + 1.
Note that if char is a signed type and the value stored in some element of the array is equivalent to 0xFF, then adding one to it is undefined behaviour (though you'll most likely print an ASCII NUL '\0').

Related

Linux C program - HEX how can I Prefix with 0x [closed]

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 3 years ago.
Improve this question
This program converts string to Hex.
#include <stdio.h>
#include <string.h>
int main(void) {
char text[] = "thank you";
int len = strlen(text);
char hex[100], string[50];
// Convert text to hex.
int i,j;
for ( i = 0, j = 0; i < len; i++, j+= 2) {
sprintf(hex + j, "%02X", text[i] );
printf("0x%X ", text[i] ); //this prints fine
}
printf("'%s' in hex is %s.\n", text, hex); //'thank you' in hex is 7468616e6b20796f75.
// Convert the hex back to a string.
len = strlen(hex);
for (i = 0, j = 0; j < len; i++, j+= 2) {
int val[1];
sscanf(hex + j, "%2x", val);
string[i] = val[0];
string[i + 1] = '\0';
}
printf("%s as a string is '%s'.\n", hex, string);
return 0;
}
But I need 0x74, 0x68, 0x61, 0x6E, 0x6B, 0x20, 0x79, 0x6F, 0x75
or assign to array
unsigned char key[] = {0x74, 0x68, 0x61, 0x6E, 0x6B, 0x20, 0x79, 0x6F, 0x75};
How to store to a string this hex value.
Use 0x in your sprintf() format, and increase the amount you increment j accordingly.
for ( i = 0, j = 0; i < len; i++, j+= 5) {
sprintf(hex + j, "0x%02X ", text[i] );
printf("0x%X ", text[i] );
}
Then you need to allow for this when scanning it. Skip over the first two characters, and then increment by 5.
There's also no need to make val an array, you just need a single int variable. And you can add the null terminator at the end of the loop, not each time through the loop.
for (i = 0, j = 2; j < len; i++, j+= 5) {
int val;
sscanf(hex + j, "%2x", &val);
string[i] = val;
}
string[i + 1] = '\0';
DEMO

Cast uint8_t to hex string (2 digits)

I'm currently using the following to print uint8_t to hex:
for(int j = 0; j < len; j++) {
printf("%02X ", bytes[j]);
}
Is it possible to do this without a for-loop and simply assign the result to a variable?
Here's one simple way:
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
if(dest_len < (val_len*2+1)) /* check that dest is large enough */
return false;
*dest = '\0'; /* in case val_len==0 */
while(val_len--) {
/* sprintf directly to where dest points */
sprintf(dest, "%02X", *values);
dest += 2;
++values;
}
return true;
}
int main() {
uint8_t values[256];
char buf[sizeof(values)*2+1]; /* one extra for \0 */
for(size_t i=0; i<256; ++i)
values[i] = i;
if(to_hex(buf, sizeof(buf), values, sizeof(values)))
printf("%s\n", buf);
}
Output:
000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
For completeness, here's a self contained version using a lookup table instead of sprintf:
bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
static const char hex_table[] = "0123456789ABCDEF";
if(dest_len < (val_len*2+1)) /* check that dest is large enough */
return false;
while(val_len--) {
/* shift down the top nibble and pick a char from the hex_table */
*dest++ = hex_table[*values >> 4];
/* extract the bottom nibble and pick a char from the hex_table */
*dest++ = hex_table[*values++ & 0xF];
}
*dest = 0;
return true;
}
Personally, I'd go for the sprintf approach, but if you badly do not want to use one of the library api, you could use something like this:
char HexLookUp[] = "0123456789abcdef";
void bytes2hex (unsigned char *src, char *out, int len)
{
while(len--)
{
*out++ = HexLookUp[*src >> 4];
*out++ = HexLookUp[*src & 0x0F];
src++;
}
*out = 0;
}
Test code:
int main(void)
{
unsigned char bytes[] = {0x00, 0x01, 0x02, 0x03, 0xDE, 0xAD, 0xBE, 0xEF, 0xCC};
char buffer[sizeof(bytes)*2 + 1];
bytes2hex(bytes, buffer, sizeof(bytes));
printf("%s\n",buffer);
return 0;
}
Output:
00010203deadbeefcc

char array not displaying when passed to a function

Why is the passing of char array not showing?
The location of the pointer is passed to a function.
char plaintext[] = {
0xCD, 0x76, 0x43, 0xF0,
0x72, 0xA4, 0xA0, 0x82,
}
Given
void displayArray(char** plaintext, int size) {
// int newSize = sizeof(**plaintext);
int i;
for(i=0; i < size; ++i) {
printf("%02X ", (0xff & *plaintext[i]));
if (((i+1)% 8) == 0) // as index starts from 0, (i+1)
printf("\n");
}
}
in main()
char* plaintextCopy;
plaintextCopy = (char*) malloc(numberOfItems*sizeof(char));
memcpy(plaintextCopy, plaintext, numberOfItems);
displayArray(&plaintextCopy, numberOfItems);
Based on your code :
void displayArray(char** plaintext, int size)
{
int i;
for(i=0; i < size; i++)
{
printf("%02X ", (0xff & (*plaintext)[i]));
if(((i+1)% 8) == 0) // as index starts from 0, (i+1)
printf("\n");
}
}
int main(void)
{
char plaintext[] = {
0xCD, 0x76, 0x43, 0xF0,
0x72, 0xA4, 0xA0, 0x82,
};
int numberOfItems = sizeof(plaintext);
char* plaintextCopy;
plaintextCopy = (char*) malloc(numberOfItems*sizeof(char));
memcpy(plaintextCopy, plaintext, numberOfItems);
displayArray(&plaintextCopy, numberOfItems);
return 0;
}
It outputs :
CD 76 43 F0 72 A4 A0 82
Also, if you're sending an array that you want to display or change the values of, you don't need to send a double pointer to a function. A regular pointer would do. You should only use double pointers if the original array changes it's location in memory, that is, it's getting a new pointer after the function returns.

char[] to uint64_t

I'm trying to convert an array of char into a uint64_t but it doesn't work.
Here's my code :
char input[8];
//Initialisation of input
int i,j;
uint64_t paquet=0;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
paquet+= (input[i] >> j) & 0x01;
paquet = paquet << 1;
}
}
Assuming that the input buffer has stored the data in a little endian representation, which means that the least significant byte is at the lowest address and the most significant byte at the highest address then you can do something like the following.
#include <stdio.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
int main(void)
{
int i;
unsigned char input[8] = {0x01, 0x02, 0x03, 0x04, 0x5, 0x06, 0x07, 0x08 };
uint64_t paquet = 0;
for( i = 7; i >= 0; --i )
{
paquet <<= 8;
paquet |= (uint64_t)input[i];
}
printf("0x%" PRIx64 "\n", paquet);
return 0;
}
You can see the working example on ideone.
If the buffer is stored in big endian mode then reverse the loop.
Thank you to m24p for pointing out a bug in my initial draft.
Maybe this ?
uint64_t paquet = input[0]<<(8*7) | input[1]<<(8*6)
| input[2]<<(8*5)
| input[3]<<(8*4)
| input[4]<<(8*3)
| input[5]<<(8*2)
| input[6]<<(8*1)
| input[7];
char input[8] = "\x01\x23\x45\x67\x89\xAB\xCD\xEF";
uint64_t paquet = *(uint64_t*)"\x1\x0\x0\x0\x0\x0\x0\x0";
if(paquet == 1){
//reverse
char *f=&input[0], *b=&input[7];
while(f<b){
char tmp = *f;
*f++ = *b;
*b-- = tmp;
}
}
paquet = *(uint64_t*)input;//memcpy(&paquet, input, sizeof(input));

Swapping endiannes in C

I have this string
c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000
How does one swap it so it becomes
000000000036cd35a97b0ff1974adde3ab5aff4dfc1379265b0108074f04ebc1
Those two are basically examples, but that is what i need to do, but not know how as i have very little knowledge of C.
The above two strings are actually unsigned char[] in the C program
P.S
Don't think i didn't go through google. I did, but i found very little of what i needed so every attempt to do that failed.
for (int i = 0; i < size; i += 2) {
myNewStr[size - i - 2] = myStr[i];
myNewStr[size - i - 1] = myStr[i + 1];
}
Something like this; probably not perfect but gives you the idea. You'll want appropriate error checking, initialization of your buffer, etc.
Edit: I made an assumption I shouldn't have, possibly. I interpreted your string as hex representations of bytes, so I took c1 as an unsigned char and switched it with 00, for example. If your string is actually lowercase c, the number 1, etc., then Micah's answer is what you want, not mine.
void reverse_string(unsigned char *buf, int length)
{
int i;
unsigned char temp;
for (i = 0; i < length / 2; i++)
{
temp = buf[i];
buf[i] = buf[length - i - 1];
buf[length - i - 1] = temp;
}
}
This seems to do what you want, include at least string.h and stdlib.h.
unsigned char *stringrev(const unsigned char *s) {
size_t n = strlen((const char *)s);
unsigned char *r = malloc(n + 1);
if (r != NULL && !(n & 1)) {
const unsigned char *fp = s;
unsigned char *rp = r + n;
for(*rp = '\0'; n > 1; n -= 2) {
*--rp = fp[1];
*--rp = fp[0];
fp += 2;
}
}
return r;
}
Slight alternative to Micah's answer. I assume that the size is precalculated and even, and check that it's greater than 0 because s-2 is potentially UB. I modify the string in-place just for variety.
static inline void swap_uchar(unsigned char *l, unsigned char *r) {
unsigned char tmp = *l;
*l = *r;
*r = tmp;
}
void reverse_pairs(unsigned char *s, size_t size) {
if (size > 0) {
for (unsigned char *l=s, *r=s+size-2; l < r; l += 2, r -= 2) {
swap_uchar(l, r);
swap_uchar(l+1, r+1);
}
}
}
If you have a string: "12ab\0" then the reverse endian of this string would be "\0ba21" .
If you have a numeric: 0x12ab then the reverse endian of this numeric would be 0xab12 .
Which one do you want.
Here is a function for converting between endian, which will handle the passed argument as a block of memory and change the endian.
Code
#include <stdio.h>
typedef struct _test {
unsigned int a, b;
} test;
/* x: base address of the memory
* n: length of the memory
*/
void reverse_endian (void *x, int n)
{
char *arr_conv, *arr, t;
arr = arr_conv = (char *) x;
arr += (n-1);
n/=2;
while (n)
{
t = *arr_conv;
*arr_conv = *arr;
*arr = t;
n--;
arr_conv++;
arr--;
}
}
int main (void)
{
char str1[] = "c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000";
char str2[] = "hellio";
/* Assigns the str1 as hex values */
unsigned char str3[] = {0xc1, 0xeb, 0x04, 0x4f, 0x07, 0x08, 0x01, 0x5b, 0x26, 0x79, 0x13, 0xfc, 0x4d, 0xff, 0x5a, 0xab, 0xe3, 0xdd, 0x4a, 0x97, 0xf1, 0x0f, 0x7b, 0xa9, 0x35, 0xcd, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00};
test x;
char q = 0x12;
int v = 0x1234abcd;
int i, n;
x.a = 0x12ab34cd;
x.b = 0x98ef76af;
printf ("\nNormal : x.a = %x x.b = %x", x.a, x.b);
reverse_endian (&x, sizeof (x));
printf ("\nReverse: x.a = %x x.b = %x", x.a, x.b);
printf ("\nNormal : q = %x", q);
reverse_endian (&q, sizeof (q));
printf ("\nReverse: q = %x", q);
printf ("\nNormal : q = %x", v);
reverse_endian (&v, sizeof (v));
printf ("\nReverse: q = %x", v);
printf ("\nNormal : str1 = %s", str1);
/* minus 1 to avoid the trailing nul character */
reverse_endian (str1, sizeof (str1) - 1);
printf ("\nReverse: str1 = %s", str1);
printf ("\nNormal : str2 = %s", str2);
/* minus 1 to avoid the trailing nul character */
reverse_endian (str2, sizeof (str2) - 1);
printf ("\nReverse: str2 = %s", str2);
printf ("\nNormal : str3 = ");
n = sizeof (str3);
for (i=0; i < n; i++)
{
printf ("%x", (str3[i]>>4)&0x0f);
printf ("%x", str3[i]&0x0f);
}
reverse_endian (str3, sizeof (str3));
printf ("\nReversed: str3 = ");
for (i=0; i < n; i++)
{
printf ("%x", (str3[i]>>4)&0x0f);
printf ("%x", str3[i]&0x0f);
}
printf ("\n");
return 0;
}
Output
Normal : x.a = 12ab34cd x.b = 98ef76af
Reverse: x.a = af76ef98 x.b = cd34ab12
Normal : q = 12
Reverse: q = 12
Normal : q = 1234abcd
Reverse: q = cdab3412
Normal : str1 = c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000
Reverse: str1 = 000000000063dc539ab7f01f79a4dd3ebaa5ffd4cf319762b5108070f440be1c
Normal : str2 = hellio
Reverse: str2 = oilleh
Normal : str3 = c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000
Reversed: str3 = 000000000036cd35a97b0ff1974adde3ab5aff4dfc1379265b0108074f04ebc1
Note that the strings str1, str2 are simply reversed, because each character of the string is one byte. The same character string you have provided is represented as byte string in str3. Its hex values are shown as output. The operations for all the data are identical, as it is only concerned to memory byte ordering.

Resources