在C中交换字节序

时间:2011-06-03 21:01:53

标签: c endianness

我有这个字符串

c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000

如何交换它以使其成为

000000000036cd35a97b0ff1974adde3ab5aff4dfc1379265b0108074f04ebc1

这两个基本上都是例子,但这就是我需要做的,但不知道我对C的了解很少。

以上两个字符串实际上是C程序中的unsigned char []

P.S 不要以为我没有通过谷歌。我做了,但我发现我所需要的很少,所以每次尝试都失败了。

5 个答案:

答案 0 :(得分:6)

for (int i = 0; i < size; i += 2) {
    myNewStr[size - i - 2] = myStr[i];
    myNewStr[size - i - 1] = myStr[i + 1]; 
}

答案 1 :(得分:1)

像这样的东西;可能不完美,但给你的想法。您需要适当的错误检查,缓冲区初始化等等。

编辑:我做了一个我不应该做的假设,可能。我将您的字符串解释为字节的十六进制表示,因此我将c1作为unsigned char并将其与00切换为例如。如果你的字符串实际上是小写c,数字1等,那么Micah的答案就是你想要的,而不是我的。

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

答案 2 :(得分:0)

这似乎做你想要的,至少包括 string.h 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;
}

答案 3 :(得分:0)

Micah回答的轻微替代品。我假设大小是预先计算的,并且检查它是否大于0,因为s-2可能是UB。我为了变化而就地修改字符串。

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);
        }
    }
}

答案 4 :(得分:0)

如果你有一个字符串:"12ab\0",那么这个字符串的反向字节将是"\0ba21"

如果你有一个数字:0x12ab,那么这个数字的反向字节将是0xab12

你想要哪一个。

这是一个在endian之间进行转换的函数,它将把传递的参数作为内存块处理并更改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

请注意,字符串str1str2只是颠倒了,因为字符串的每个字符都是一个字节。您提供的相同字符串在str3中表示为字节字符串。其十六进制值显示为输出。所有数据的操作都是相同的,因为它只涉及内存字节排序。