Use LINQ to XOR Bytes Together
How can I use LINQ to to XOR
bytes together in an array? I'm taking the output of an MD5 hash and would like to XOR
every four bytes together so that I can get a 32 bit int
out of it. I could easily do this with a loop, but I thought it was an interesting problem for LINQ.
开发者_如何转开发public static byte[] CompressBytes(byte[] data, int length)
{
byte[] buffer = new byte[length];
for (int i = 0; i < data.Length; i++)
{
for (int j = 0; j < length; j++)
{
if (i * length + j >= data.Length)
break;
buffer[j] ^= data[i * length + j];
}
}
return buffer;
}
Slightly off topic, but is this even a good idea? If I need a int
, would I be better off with a different hash function, or should I just take the first 4 bytes of the MD5 because XOR
ing them all wouldn't help any? Comments are welcome.
You can use the IEnumerable.Aggregate
function (not actually LINQ, but most people refer to the LINQ-related extension methods as LINQ) to perform a custom aggregate. For example, you could compute the total XOR of a list of byte
s like this:
var xor = list.Aggregate((acc, val) => (byte)(acc ^ val));
You can create a virtually unreadable chain of extension method calls to do what you're after:
int integer = BitConverter.ToInt32(Enumerable.Range(0, 3).
Select(i => data.Skip(i * 4).Take(4).
Aggregate((acc, val) => (byte)(acc ^ val))).ToArray(), 0)
To address the "off topic" part, I'd suggest just lopping off the first 32 bits of the MD5 hash. Or consider a simpler non-crypto hash such as CRC32.
Like other cryptographic hashes, MD5 is supposed to appear as random as possible, so XOR'ing other bytes won't really make a difference, IMO.
In case you need xor of 2 byte arrays: byteArray1.Select((x, i) => (byte)(x ^ byteArray2[i])).ToArray();
精彩评论