Reputation: 119
I would like to know how to manipulate bits from a ByteArray. What I need is to shift the bits according to a 'table' that I have.
Table:
Bit 0 -> Bit 26 Bit 1 -> Bit 31 Bit 2 -> Bit 17 ... Bit 31 -> Bit 5
I convert the ByteArray to BitArray using this method
public static BitArray ByteArraytoBitArray(byte[] bytes)
{
BitArray bits = new BitArray(bytes);
return bits;
}
But I am stuck there, I don't know how to shift the bits according to the table and then back to ByteArray.
EDIT:
Code Snipet:
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
private void button3_Click(object sender, EventArgs e)
{
string featherearring = "00804804A02A1CA20100000000000000D2F8B6FABBB700000000000000000000";
var strarray = StringToByteArray(featherearring);
byte[] strarray_comp = Enc.Encrypt(strarray);
string conv = BitConverter.ToString(strarray_comp);
MessageBox.Show(conv.Replace("-", ""));
}
public static byte[] BitArrayToByteArray(BitArray bits)
{
byte[] bytes = new byte[bits.Length / 8];
bits.CopyTo(bytes, 0);
return bytes;
}
public static byte[] Encrypt(byte[] input)
{
BitArray source = new BitArray(input);
BitArray target = new BitArray(source.Length);
target[26] = source[0];
target[31] = source[1];
target[17] = source[2];
target[10] = source[3];
target[30] = source[4];
target[16] = source[5];
target[24] = source[6];
target[2] = source[7];
target[29] = source[8];
target[8] = source[9];
target[20] = source[10];
target[15] = source[11];
target[28] = source[12];
target[11] = source[13];
target[13] = source[14];
target[4] = source[15];
target[19] = source[16];
target[23] = source[17];
target[0] = source[18];
target[12] = source[19];
target[14] = source[20];
target[27] = source[21];
target[6] = source[22];
target[18] = source[23];
target[21] = source[24];
target[3] = source[25];
target[9] = source[26];
target[7] = source[27];
target[22] = source[28];
target[1] = source[29];
target[25] = source[30];
target[5] = source[31];
return BitArrayToByteArray(target);
}
my input byte array is "00804804A02A1CA20100000000000000D2F8B6FABBB700000000000000000000" and my output with zimdanen's code is "5012000000000000000000000000000000000000000000000000000000000000" and it should be "501200002FD901000000000400000000BFE8C4DB140D11F40000000000000000" As you can see, it gets the first 2 bytes right, but the rest is are all null.
Upvotes: 0
Views: 2742
Reputation: 134125
Your first problem is that you have an array of 32 bytes that you're converting to a BitArray
. You'll find that the value of the source.Count
property is 256. target.Count
, on the other hand, is only 32. So your Encrypt
method only changes the first 32 bits of the bit array, which corresponds four bytes -- eight of your hexadecimal characters. The rest of your array will be nulls.
You can verify this by changing your BitArrayToByteArray
method to fill the destination with 0xFF before doing the copy:
public static byte[] BitArrayToByteArray(BitArray bits)
{
byte[] bytes = new byte[bits.Length / 8];
// Fill the array with 0xFF to illustrate.
for (int i = 0; i < bytes.Length; ++i)
{
bytes[i] = 0xFF;
}
bits.CopyTo(bytes, 0);
return bytes;
}
I think you'll find that the result is "50120000FFFFFF...."
It's hard to tell exactly what you're trying to do. If you want to scramble the bytes in your string, there's no need to use a BitArray
. If you really want to scramble the bits, then you need to scramble ALL the bits. Without more information about what you're trying to do, I don't have a suggestion. Except that perhaps you should use one of the many existing encryption algorithms rather than trying to roll your own.
Upvotes: 1
Reputation: 5626
Does it need to be in place? You can create a new BitArray and just copy the bits over:
BitArray source = new BitArray(bytes);
// Create target array.
BitArray target = new BitArray(source.Length);
// Map bits.
// ...
target[26] = source[0];
// ...
Or, depending on how you want to maintain your mapping "table", you can do it like this:
// Setup mapping - <source, target>.
Dictionary<int, int> mapping = new Dictionary<int, int>();
// ...
mapping.Add(0, 26);
// ...
BitArray source = new BitArray(bytes);
// Create target array.
BitArray target = new BitArray(source.Length);
// Map bits.
foreach (int sourceIndex in mapping.Keys)
{
int targetIndex = mapping[sourceIndex];
target[targetIndex] = source[sourceIndex];
}
Upvotes: 1