C# Problem using blowfish NET: How to convert from Uint32[] to byte[] - c#

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!

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

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

Related

Rewrite C++ function to C# (pass pointer to next element in array)

I need to rewrite this C++ function to C#
bool DesDecrypt(const BYTE *InBuff, DWORD dwInBuffSize, BYTE *OutBuff, DWORD dwOutBuffSize, const char *TerminalID)
{
...
for(DWORD i = 0 ; i < dwInBuffSize/8 ; i++)
DES.des_ecb_encrypt((des_cblock *)InBuff+i, (des_cblock *)OutBuff+i, sched, DES_DECRYPT) ;
}
The place I am stuck is pointer arithmetic. On C++ side you can see author uses
InBuff+i
So it is advancing pointer and passing it to function.
On C# my function looks like this:
public static bool DesDecrypt(byte[] inBuff, uint inBuffSize, byte[] outBuff, uint outBufSize, string terminalID)
{
.....
}
I am stuck how to rewrite above loop(particularly how to pass pointer to next element in byte array) to C#. In C# there is no pointer arithmetic so if I do similar, it will just pass i'th value of byte array.
So how can I simulate on C# passing pointer to the next element in array ?
This is my decrypt function in C#
public static byte[] DecryptDES_ECB(byte [] ciphertext, byte [] key)
which I should use instead of C++ version: DES.des_ecb_encrypt
I am looking for such wrapper as a solution on C# side
public static byte[] DecryptDES_ECB(byte[] ciphertext, int cipherOffset, byte[] key)
{
byte [] tmp = new byte [ciphertext.Length - cipherOffset];
for(int i = 0; i<ciphertext.Length - cipherOffset; i++)
{
tmp[i] = ciphertext[cipherOffset + i];
}
return DecryptDES_ECB(tmp, key);
}
Do you think this should work? Now I will call this function on C# side in loop and pass offset as in C++.
If you use a LINQ extension and write inBuff.Skip(i) you will get an IEnumerable that yilds it's elements starting with the i inBuff element. Unless you call ToList method no copying and additional memory allocation will appear but you can treat and use your new IEnumerable like it's a subarray.
After your update:
Easiest solution would be to get some sort of subarray of your inBuff and outBuff, then perform your DecryptDES_ECB()-function and copy your results into your original arrays afterwards.
public static void DecryptDES_ECB(byte[] ciphertext, byte[] decryptedtext, int cipherOffset, byte[] key)
{
byte [] tmpCipher = new byte [ciphertext.Length - cipherOffset];
Array.copy(ciphertext, cipherOffset, tmpCipher, 0, tmpCipher.Length);
byte [] tmpDecrypt = DecryptDES_ECB(tmp, key);
Array.copy(tmpDecrypt, 0, decryptedtext, cipherOffset, tmpDecrypt.Length);
}
This method has not been tested and I don't know the underlaying library, so I can not guarantee for correctness. But generally this would be an easy (but rather slow) attempt on solving your general problem.
EDIT:
Just some additional info on Array.Copy: It performs a memmove which internally (usually) performs a call to memcpy, which is pretty damn fast. (Usually) a lot faster than your loop can possibly be.

Converting byte[] to an object

I'm trying to convert an object which I have in a byte[] to an object.
I've tried using this code I found online:
object byteArrayToObject(byte[] bytes)
{
try
{
MemoryStream ms = new MemoryStream(bytes);
BinaryFormatter bf = new BinaryFormatter();
//ms.Position = 0;
return bf.Deserialize(ms,null);
}
catch
{
return null;
}
}
SerializationException: "End of Stream encountered before parsing was
completed.".
I've tried it with the ms.Position = 0 line uncommented of course too...
bytes[] is only 8 bytes long, each byte isn't null.
Suggestions?
[edit]
The byte[] was written to a binary file from a c++ program using something along the lines of
void WriteToFile (std::ostream& file,T* value)
{
file.write(reinterpret_cast<char*>(value), sizeof(*T))
}
Where value may be a number of different types.
I can cast to some objects okay from the file using BitConverter, but anything BitConverter doesn't cover I can't do..
As was stated by cdhowie, you will need to manually deserialize the encoded data. Based on the limited information available, you may either want an array of objects or an object containing an array. It looks like you have a single long but there is no way to know from your code. You will need to recreate your object in its true form so take the below myLong as a simple example for a single long array. Since it was unspecified I'll assume you want a struct containing an array like:
public struct myLong {
public long[] value;
}
You could do the same thing with an array of structs, or classes with minor changes to the code posted below.
Your method will be something like this: (written in the editor)
private myLong byteArrayToObject(byte[] bytes) {
try
{
int len = sizeof(long);
myLong data = new myLong();
data.value = new long[bytes.Length / len];
int byteindex = 0;
for (int i = 0; i < data.value.Length; i++) {
data.value[i] = BitConverter.ToInt64(bytes,byteindex);
byteindex += len;
}
return data;
}
catch
{
return null;
}
}

Is this the best way to convert multi dimensional array of Byte to List of Byte-arrays?

I am having a method which must return List of Bytes as follow:
public List<byte[]> ExportXYZ(IPAddress ipAddress, WebCredential cred)
Inside above method I am calling third party method which returns a multi-dimensional byte array:
byte[][] tempBytes = xyzProxy.ExportCertificates();
So now I need to convert byte[][] to List<byte[]>.
I wrote below code
private List<byte[]> ConvertToSigleDimensional(byte[][] source)
{
List<byte[]> listBytes = null;
for(int item=0;item < source.Length;item++)
{
listBytes.Add(source[i][0]);
}
return listBytes;
}
I feel this is not a good way of coding. Can anyone help me to write proper code for the conversion?
Your method doesn't return a list of byte - it returns a list of byte[], of byte arrays.
Since your input is an array of byte arrays, you can probably simply convert from one to the other.
With LINQ:
byte[][] arr = ...;
List<byte[]> list = arr.ToList();
Without LINQ:
byte[][] arr = ...;
List<byte[]> list = new List<byte[]>(arr);

Convert IEnumerable<byte[]> to byte[]

var r = from s in tempResult
select Encoding.GetEncoding("iso-8859-1").GetBytes(s);
I understand, this returns IEnumerable<byte[]>, but I looking for LINQ way to convert the whole IEnumerable<byte[]> to byte[].
None of the answers provided so far will work, because they will convert the IEnumerable<byte[]> to byte[][]. If your goal is to take all of the arrays in the enumerable and produce one big array, try this:
byte[] result = r.SelectMany(i => i).ToArray();
See this ideone example.
Note that this is not the most efficient way to do this. It would be faster to convert the original query result to a list, then compute the sum of the array lengths. Once that is done, you can allocate the final array immediately, then make one more pass over the result list and copy each result array's contents into the larger array.
The above LINQ query definitely makes this task easy, but it will not be fast. If this code becomes a bottleneck in the application, consider rewriting it this way.
I might as well provide an example of a more efficient implementation:
public static T[] JoinArrays<T>(this IEnumerable<T[]> self)
{
if (self == null)
throw new ArgumentNullException("self");
int count = 0;
foreach (var arr in self)
if (arr != null)
count += arr.Length;
var joined = new T[count];
int index = 0;
foreach (var arr in self)
if (arr != null)
{
Array.Copy(arr, 0, joined, index, arr.Length);
index += arr.Length;
}
return joined;
}
Note that whatever enumerable you pass in will be enumerated twice, so it would be a good idea to pass in a list or an array instead of a query, if that query is expensive.
Are you sure that's what you want to do? This code already returns a byte array:
Encoding.GetEncoding("iso-8859-1").GetBytes(s);
In any case, if you want to convert the enumeration to an array, you would do so like this:
var myArray = (from s in tempResult
select Encoding.GetEncoding("iso-8859-1").GetBytes(s)).ToArray();
EDIT
After your edit, I see I've misunderstood what you're trying to accomplish. If I understand correctly now, you're trying to get a byte array containing concatenated strings in tempResult? I would so it like this:
var concatenated = String.Join("", tempResult.ToArray());
var byteArray = Encoding.GetEncoding("iso-8859-1").GetBytes(concatenated);
What about ToArray extension method?
byte[] array = r.SelectMany(a => a).ToArray();
var r = (from s in tempResult
select Encoding.GetEncoding("iso-8859-1").GetBytes(s)
).ToArray();

Read an array of structs in C#

I've seen here , and also googling for "marshal" several ways to convert a byte array to a struct.
But what I'm looking for is if there is a way to read an array of structs from a file (ok, whatever memory input) in one step?
I mean, load an array of structs from file normally takes more CPU time (a read per field using a BinaryReader) than IO time. Is there any workaround?
I'm trying to load about 400K structs from a file as fast as possible.
Thanks
pablo
Following URL may be of interest to you.
http://www.codeproject.com/KB/files/fastbinaryfileinput.aspx
Or otherwise I think of pseudo code like the following:
readbinarydata in a single shot and convert back to structure..
public struct YourStruct
{
public int First;
public long Second;
public double Third;
}
static unsafe byte[] YourStructToBytes( YourStruct s[], int arrayLen )
{
byte[] arr = new byte[ sizeof(YourStruct) * arrayLen ];
fixed( byte* parr = arr )
{
* ( (YourStruct * )parr) = s;
}
return arr;
}
static unsafe YourStruct[] BytesToYourStruct( byte[] arr, int arrayLen )
{
if( arr.Length < (sizeof(YourStruct)*arrayLen) )
throw new ArgumentException();
YourStruct s[];
fixed( byte* parr = arr )
{
s = * ((YourStruct * )parr);
}
return s;
}
Now you can read bytearray from the file in a single shot and convert back to strucure using BytesToYourStruct
Hope you can implement this idea and check...
I found a potential solution at this site -
http://www.eggheadcafe.com/software/aspnet/32846931/writingreading-an-array.aspx
It says basically to use Binary Formatter like this:
FileStream fs = new FileStream("DataFile.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, somestruct);
I also found two questions from this site - Reading a C/C++ data structure in C# from a byte array
and
How to marshal an array of structs - (.Net/C# => C++)
I haven't done this before, being a C# .NET beginner myself. I hope this solution helps.

Categories

Resources