这似乎是一个愚蠢的问题,但我找不到答案......
这是来自维基百科的XXTEA代码:
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX ((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z));
void btea(uint32_t *v, int n, uint32_t const k[4]) {
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) { /* Coding Part */
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do {
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
y = v[p+1], z = v[p] += MX;
y = v[0];
z = v[n-1] += MX;
} while (--rounds);
} else if (n < -1) { /* Decoding Part */
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do {
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
z = v[p-1], y = v[p] -= MX;
z = v[n-1];
y = v[0] -= MX;
} while ((sum -= DELTA) != 0);
}
}
我将其移植到C#。我不知道我在忽视什么,但加密的结果存储在哪里?我假设它在v中,但是来自v的数据从未设置,只能读取。
我没看到什么?
答案 0 :(得分:7)
我在谷歌搜索“XXTEA C#”时找到了这个页面。找不到任何现成的实现,所以我做了我自己的。凭借闭包的魔力,它实际上是参考代码的逐字副本。我已将它发布给到达这里的任何人。
请注意,虽然这会接受任意长度的字节数组,但返回数组的长度始终是4的倍数。并且,与参考实现不同,此实现返回修改后的数据,而不是更改原始数据。
using System;
namespace Encryption
{
public enum XXTEAMode
{
Encrypt,
Decrypt
}
static public class XXTEA
{
static public byte[] Code(byte[] data, uint[] k, XXTEAMode mode)
{
uint[] v = new uint[(int)Math.Ceiling((float)data.Length / 4)];
Buffer.BlockCopy(data, 0, v, 0, data.Length);
unchecked
{
const uint DELTA = 0x9e3779b9;
uint y = 0, z = 0, sum = 0, p = 0, rounds = 0, e = 0;
int n = v.Length;
Func<uint> MX = () => (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (k[(p & 3) ^ e] ^ z)));
if (mode == XXTEAMode.Encrypt)
{
rounds = (uint)(6 + 52 / n);
z = v[n - 1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
{
y = v[p + 1];
z = v[p] += MX();
}
y = v[0];
z = v[n - 1] += MX();
} while (--rounds > 0);
}
else
{
rounds = (uint)(6 + 52 / n);
sum = rounds * DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p = (uint)(n - 1); p > 0; p--)
{
z = v[p - 1];
y = v[p] -= MX();
}
z = v[n - 1];
y = v[0] -= MX();
} while ((sum -= DELTA) != 0);
}
}
byte[] rvl = new byte[v.Length * 4];
Buffer.BlockCopy(v, 0, rvl, 0, rvl.Length);
return rvl;
}
}
}
答案 1 :(得分:2)
在编码部分:z = v[n-1] += MX;
在解码部分:y = v[p] -= MX;
这些行在v数组的元素上执行+ =,然后将新值复制到z或y中。编写代码的人优先考虑简洁而不是清晰度,这在实际应用中通常不是一件好事。
答案 2 :(得分:1)
运算符= - = + =在表达式中具有相同的优先级,并且它们根据C ++标准5.17从右到左关联(我相信在C中有相同的规则)。例如,这个:
y = v[p] -= MX;
可以替换为:
v[p] -= MX; // <<< modification of data here
y = v[p];
答案 3 :(得分:1)
v在此行中设置,例如:
y = v[0] -= MX;
这也可以写成:
v[0] = v[0] - MX;
y = v[0];
答案 4 :(得分:1)
指针v
末尾的数组中的数据已更新:
v[p] += MX;
...
z = v[n-1] += MX;
...
z = v[p-1], y = v[p] -= MX;
...
y = v[0] -= MX;
是的; 引用的数据是v
,已更新。