Reputation: 2053
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.
Upvotes: 1
Views: 584
Reputation: 61990
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.
#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;
}
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.
Upvotes: 0
Reputation: 279415
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);
}
}
}
Upvotes: 0
Reputation: 146251
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;
}
Upvotes: 0
Reputation: 14437
for (int i = 0; i < size; i += 2) {
myNewStr[size - i - 2] = myStr[i];
myNewStr[size - i - 1] = myStr[i + 1];
}
Upvotes: 6
Reputation: 16007
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;
}
}
Upvotes: 1