gpt4 book ai didi

c++ - 半字节移动

转载 作者:行者123 更新时间:2023-11-30 02:07:45 27 4
gpt4 key购买 nike

我正在研究一种加密算法,我想知道如何将以下代码更改为更简单的代码以及如何反转此代码。

typedef struct 
{
unsigned low : 4;
unsigned high : 4;
} nibles;

static void crypt_enc(char *data, int size)
{
char last = 0;

//...

// Pass 2
for (i = 0; i < size; i++)
{
nibles *n = (nibles *)&data[i];

n->low = last;
last = n->high;
n->high = n->low;
}
((nibles *)&data[0])->low = last;
}

数据是这段代码的输入和输出。

最佳答案

您将每个字节的两个半字节设置为相同的东西,因为您最终将高半字节设置为与低半字节相同。我假设这是一个错误,您的意图是移动数据中的所有半字节,从一个字节转移到另一个字节,然后滚动。 Id est,ABCDEF(半字节顺序从低到高)将变为 FABCDE。如果我说错了,请纠正我。

代码应该是这样的:

static void crypt_enc(char *data, int size)
{
char last = 0;

//...

// Pass 2
for (i = 0; i < size; i++)
{
nibles *n = (nibles *)&data[i];

unsigned char old_low = n->low;
n->low = last;
last = n->high;
n->high = old_low;
}
((nibles *)&data[0])->low = last;
}

现在还好吗?否。仅当 nibbles 的对齐方式不比 char 的对齐方式更严格时,转换为 nibbles* 才是明确定义的。和 that is not guaranteed (但是,对于 small change ,GCC 会生成具有相同对齐方式的类型)。

就个人而言,我会完全避免这个问题。以下是我的做法:

void set_low_nibble(char& c, unsigned char nibble) {
// assumes nibble has no bits set in the four higher bits)
unsigned char& b = reinterpret_cast<unsigned char&>(c);
b = (b & 0xF0) | nibble;
}

void set_high_nibble(char& c, unsigned char nibble) {
unsigned char& b = reinterpret_cast<unsigned char&>(c);
b = (b & 0x0F) | (nibble << 4);
}

unsigned char get_low_nibble(unsigned char c) {
return c & 0x0F;
}

unsigned char get_high_nibble(unsigned char c) {
return (c & 0xF0) >> 4;
}

static void crypt_enc(char *data, int size)
{
char last;

//...

// Pass 2
for (i = 0; i < size; ++i)
{
unsigned char old_low = get_low_nibble(data[i]);
set_low_nibble(data[i], last);
last = get_high_nibble(data[i]);
set_high_nibble(data[i], old_low);
}
set_low_nibble(data[0], last);
}

反过来就是将“低”变为“高”,反之亦然;滚动到最后一个半字节,而不是第一个;并以相反的方向遍历数据:

for (i = size-1; i >= 0; --i)
{
unsigned char old_high = get_high_nibble(data[i]);
set_high_nibble(data[i], last);
last = get_low_nibble(data[i]);
set_low_nibble(data[i], old_high);
}
set_high_nibble(data[size-1], last);

如果你愿意,你可以摆脱对临时 last 的所有传输。你只需要保存所有的最后一个半字节,然后直接移动半字节而不使用另一个变量:

last = get_high_nibble(data[size-1]);
for (i = size-1; i > 0; --i) // the last one needs special care
{
set_high_nibble(data[i], get_low_nibble(data[i]));
set_low_nibble(data[i], get_high_nibble(data[i-1]));
}
set_high_nibble(data[0], get_low_nibble(data[0]));
set_low_nibble(data[0], last);

关于c++ - 半字节移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7519665/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com