2

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!

Oded
  • 489,969
  • 99
  • 883
  • 1,009
Ivan Prodanov
  • 34,634
  • 78
  • 176
  • 248
  • This question is interesting not only for apps that use Blowfish, but for any app that needs to do data manipulation to convert between types of arrays. – Cheeso Mar 28 '09 at 22:22

3 Answers3

5

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();
}

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
4

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();
Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • @JaredPar I get this error: 'System.Array' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?) //end error – Ivan Prodanov Mar 28 '09 at 14:26
  • @John, are you using VS2005 or VS2008? If 2008, make sure you add using System.Linq to the top of the file. If not, I'll update for a VS2005 solution – JaredPar Mar 28 '09 at 14:27
  • @John: You can use my code (which does the same), or reference System.Linq and use C# 3 / VS 2008. – Reed Copsey Mar 28 '09 at 14:27
  • @Reed Copsey,I'll try your code,but I might need a function that converts byte[] to Uint32[] ,because below this code I call blowfish.Encode @JaredPar,I'm very new to C#,my previous language is Delphi and I cannot get used to C#.I'm using C# Express 2008.Could you explain step by step what to do. – Ivan Prodanov Mar 28 '09 at 14:33
  • @John, if you're using C# Expression 2008, either solution should work. If the first one is not working, go to the top of the file and make sure that you have a line saying using System.Linq; – JaredPar Mar 28 '09 at 14:36
  • @JaredPar, Thank you too,could you give a solution how to eventually turn those 8 bytes back into an array of Uint32? Non LINQ solution would be better,because im new. – Ivan Prodanov Mar 28 '09 at 14:41
  • @John: I added it to my answer for you. – Reed Copsey Mar 28 '09 at 14:42
  • Ok.You both know too much,I digged up both answers.@Reed Copsey - yours is the one I accepted,but I want to Thank JaredPar too.Thank you guys! – Ivan Prodanov Mar 28 '09 at 14:46
  • @Jared - you can make the non-LINQ solution even more concise by using Array.ForEach(). – Cheeso Mar 28 '09 at 22:21
0

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).

Community
  • 1
  • 1
Omer Mor
  • 5,216
  • 2
  • 34
  • 39