C# Problem using blowfish NET: How to convert from Uint32[] to byte[]
Question
In C#,I'm using Blowfish.NET 2.1.3's BlowfishECB.cs file(can be found here)
In C++,It's unknown,but it is similiar.
In C++,the Initialize(blowfish) procedure is the following:
void cBlowFish::Initialize(BYTE key[], int keybytes)
In C#,the Initialize(blowfish) procedure is the same
public void Initialize(byte[] key, int ofs, int len)
This is the problem:
This is how the key is initialized in C++
DWORD keyArray[2] = {0}; //declaration
...some code
blowfish.Initialize((LPBYTE)keyArray, 8);
As you see,the key is an array of two DWORDS,which is 8 bytes total.
In C# I declare it like that,but I get an error
BlowfishECB blowfish = new BlowfishECB();
UInt32[] keyarray = new UInt32[2];
..some code
blowfish.Initialize(keyarray, 0, 8);
The error is:
Argument '1': cannot convert from 'uint[]' to 'byte[]'
What am I doing wrong?
Thanks in advance!
Solution
You can use BitConverter to get the bytes from a UInt32.
To do this, you'll need to convert each element in a loop. I would do something like:
private byte[] ConvertFromUInt32Array(UInt32[] array)
{
List<byte> results = new List<byte>();
foreach(UInt32 value in array)
{
byte[] converted = BitConverter.GetBytes(value);
results.AddRange(converted);
}
return results.ToArray();
}
To go back:
private UInt32[] ConvertFromByteArray(byte[] array)
{
List<UInt32> results = new List<UInt32>();
for(int i=0;i<array.Length;i += 4)
{
byte[] temp = new byte[4];
for (int j=0;j<4;++j)
temp[j] = array[i+j];
results.Add(BitConverter.ToUInt32(temp);
}
return results.ToArray();
}
OTHER TIPS
If you are using VS2008 or C# 3.5, try the following LINQ + BitConverter solution
var converted =
keyArray
.Select(x => BitConverter.GetBytes(x))
.SelectMany(x => x)
.ToArray();
Breaking this down
- The Select converts every UInt32 into a byte[]. The result is an IEnumerable<byte[]>
- The SelectMany calls flattes the IEnumerable<byte[]> to IEnumerable<byte>
- ToArray() simply converts the enumerable into an array
EDIT Non LINQ solution that works just as well
List<byte> list = new List<byte>();
foreach ( UInt32 k in keyArray) {
list.AddRange(BitConverter.GetBytes(k));
}
return list.ToArray();
If you need a faster way to convert your value types, you can use the hack I described in the following answer: What is the fastest way to convert a float[] to a byte[]?
This hack avoid memory allocations and iterations. It gives you a different view of your array in O(1).
Of course you should only use this if performance is an issue (avoid premature optimization).