字节交换位操作

时间:2015-01-28 22:50:52

标签: c

我有这个函数叫做字节交换我应该实现。我们的想法是函数需要3个整数(int x,int y,int z),函数将交换int x的y和z字节。限制几乎仅限于逐位操作(没有循环,没有if语句或逻辑运算符,如==)。

我不相信我充分提出了这个问题,所以我要重新尝试

我现在明白了

byte 1 is referring to bits 0-7
byte 2 is referring to bits 8-15
byte 3                      16-23
byte 4                      24-31

我的函数应该采用3个整数输入,x,y和z。然后x上的y字节和z字节必须切换

int byteSwap(int x, int y, int z)

前工作职能

byteSwap(0x12345678, 1, 3) = 0x56341278
byteSwap(0xDEADBEEF, 0, 2) = 0xDEEFBEAD

我的原始代码中有一些巨大的错误,即我正在考虑一个字节为2位而不是8位。我正在努力解决的主要问题是我不知道如何访问这些位在给定字节的内部。例如,当我给出字节4和5时,如何访问其受尊重的位?据我所知,我找不到给定字节与其起始位之间的数学关系。我假设我必须转移然后屏蔽,并将它们保存到变量中。尽管我甚至无法做到这一点。

2 个答案:

答案 0 :(得分:1)

使用((1ll << ((i + 1) * 8)) - 1) >> (i * 8)提取第i个字节。使用XOR运算符进行交换,并将交换的字节放在它们的位置。

int x, y, z;
y = 1, z = 3;
x = 0x12345678;

int a, b; /* bytes to swap */
a = (x & ((1ll << ((y + 1) * 8)) - 1)) >> (y * 8);
b = (x & ((1ll << ((z + 1) * 8)) - 1)) >> (z * 8);

/* swap */
a = a ^ b;
b = a ^ b;
a = a ^ b;

/* put zeros in bytes to swap */
x = x & (~((0xff << (y * 8))));
x = x & (~((0xff << (z * 8))));

/* put new bytes in place */
x = x | (a << (y * 8));
x = x | (b << (z * 8));

答案 1 :(得分:0)

当你说&#39; x&#39; 的y和z字节时,这意味着x是一个字节数组,而不是整数。如果是这样的话:

x[z] ^= x[y];
x[y] ^= x[z];
x[z] ^= x[y];

将通过交换x[y]x[z]

来实现这一目标

编辑后,您似乎想要交换32位整数的单个字节:

在小端机器上:

int
swapbytes (int x, int y, int z)
{
    char *b = (char *)&x;
    b[z] ^= b[y];
    b[y] ^= b[z];
    b[z] ^= b[y];
    return x;
}

在大端机器上:

int
swapbytes (int x, int y, int z)
{
    char *b = (char *)&x;
    b[3-z] ^= b[3-y];
    b[3-y] ^= b[3-z];
    b[3-z] ^= b[3-y];
    return x;
}

严格解释规则,你甚至不需要xor技巧:

int
swapbytes (int x, int y, int z)
{
    char *b = (char *)&x;
    char tmp = b[z];
    b[z] = b[y];
    b[y] = tmp;
    return x;
}

在大端机器上:

int
swapbytes (int x, int y, int z)
{
    char *b = (char *)&x;
    char tmp = b[3-z];
    b[3-z] = b[3-y];
    b[3-y] = tmp;
    return x;
}

如果你想使用位移(注意<<3乘以8):

int
swapbytes (unsigned int x, int y, int z)
{
    unsigned int masky = 0xff << (y<<3);
    unsigned int maskz = 0xff << (z<<3);
    unsigned int origy = (x & masky) >> (y<<3);
    unsigned int origz = (x & maskz) >> (z<<3);
    return (x & ~masky & ~maskz) | (origz << (y<<3)) | (origy << (z<<3));
}