c# 在字节数组上应用 64 位异或



我想应用双字节数组的64 XOR操作。这是使用unsafe的正确方法吗

我已经尝试了以下方法而不使用unsafe. 但我想要比这快一点

for (int i=0; i< oldBlock.Length;i++)
{
{
oldblock[i] ^= (newblock[i]);
}

下面的 XOR 操作会错过最后一个字节,如下代码 XOR 每次 8 个字节。

如何实现这一点。

static void Main(string[] args)
{

byte[] a = new byte[10];
byte[] b = new byte[10];
Random r = new Random();
r.NextBytes(a);
a.CopyTo(b, 0);
XOr64(a, b);
foreach (byte c in a)
{
Console.WriteLine(c);
}

Console.ReadKey();

}    
public static unsafe void XOr64(byte[] oldBlock, byte[] newblock)
{
try
{
fixed (byte* byteA = oldBlock)
fixed (byte* byteB = newblock)
{
long* ppA = (long*)byteA;
long* ppB = (long*)byteB;
for (int p = 0; p < oldBlock.Length/8; p++)
{
*ppA ^= *ppB;
ppA++;
ppB++;
}
}
}
catch
{
}

}

如果一次8 字节方面对您来说效果很好,并且您确定需要额外的性能,您可以扩展该方法以单独覆盖剩余的字节 - 最多为 7 个字节:

public static unsafe void XOr64(byte[] oldBlock, byte[] newBlock)
{
// First XOR as many 64-bit blocks as possible, for the sake of speed
fixed (byte* byteA = oldBlock)
fixed (byte* byteB = newBlock)
{
long* ppA = (long*) byteA;
long* ppB = (long*) byteB;
int chunks = oldBlock.Length / 8;
for (int p = 0; p < chunks; p++)
{
*ppA ^= *ppB;
ppA++;
ppB++;
}
}
// Now cover any remaining bytes one byte at a time. We've
// already handled chunks * 8 bytes, so start there.
for (int index = chunks * 8; index < oldBlock.Length; index++)
{
oldBlock[index] ^= newBlock[index];
}
}

以下是使用Span<>而不是不安全代码实现@Jon Skeet 算法:

public static void Xor64(Span<byte> bytes, ReadOnlySpan<byte> mask) {
int chunks = mask.Length / 8;
int chunksBounds = chunks * 8;
Xor64(MemoryMarshal.Cast<byte, long>(bytes[..chunksBounds]), MemoryMarshal.Cast<byte, long>(mask[..chunksBounds]));
for (int i = chunksBounds;i < mask.Length;i++) {
bytes[i] ^= mask[i];
}
}
public static void Xor64(Span<long> longs, ReadOnlySpan<long> mask) {
for (int i = 0;i < longs.Length;i++) {
longs[i] ^= mask[i];
}
}

最新更新