How do I left pad a byte array efficiently - c#

Assuming I have an array
LogoDataBy
{byte[0x00000008]}
[0x00000000]: 0x41
[0x00000001]: 0x42
[0x00000002]: 0x43
[0x00000003]: 0x44
[0x00000004]: 0x31
[0x00000005]: 0x32
[0x00000006]: 0x33
[0x00000007]: 0x34
I would like to create an array of an arbitrary length and left pad it with 0x00
newArray
{byte[0x00000010]}
[0x00000000]: 0x00
[0x00000001]: 0x00
[0x00000002]: 0x00
[0x00000003]: 0x00
[0x00000004]: 0x00
[0x00000005]: 0x00
[0x00000006]: 0x00
[0x00000007]: 0x00
[0x00000008]: 0x41
[0x00000009]: 0x42
[0x0000000a]: 0x43
[0x0000000b]: 0x44
[0x0000000c]: 0x31
[0x0000000d]: 0x32
[0x0000000e]: 0x33
[0x0000000f]: 0x34
I have my current snippet here
string test = "ABCD1234";
byte[] LogoDataBy = ASCIIEncoding.ASCII.GetBytes(test);
var newArray = new byte[16];
var difference = newArray.Length - LogoDataBy.Length;
for (int i = 0; i < LogoDataBy.Length; i++)
{
newArray[difference + i] = LogoDataBy[i];
}
Is there a more efficient way to do this?

I would recommend starting with Array.Copy like this:
string test = "ABCD1234";
byte[] LogoDataBy = ASCIIEncoding.ASCII.GetBytes(test);
var newArray = new byte[16];
var startAt = newArray.Length - LogoDataBy.Length;
Array.Copy(LogoDataBy, 0, newArray, startAt, LogoDataBy.Length);
If you really need the speed you can do Buffer.BlockCopy too:
string test = "ABCD1234";
byte[] LogoDataBy = ASCIIEncoding.ASCII.GetBytes(test);
var newArray = new byte[16];
var startAt = newArray.Length - LogoDataBy.Length;
Buffer.BlockCopy(LogoDataBy, 0, newArray, startAt, LogoDataBy.Length);
Note that I did not check the length of the array you provided - you should take care that it's big enough.

Depending on how you define "more efficient" then this might be worth doing:
var newArray =
Enumerable
.Repeat<Byte>(0, 16 - LogoDataBy.Length)
.Concat(LogoDataBy)
.ToArray();
This may not be computationally more efficient, but in terms of making the code clear and maintainable you might consider this am efficient way to code.

There are some other overloads of GetBytes that you can use. One of them allows you to specify a starting index in the array: http://msdn.microsoft.com/en-us/library/595a8te7%28v=vs.110%29.aspx
You can use the GetByteCount method on the encoding class to get the number of bytes that will exist after the encoding, although adding this additional call may negate any performance benefit. You may know that the byte count exactly matches the string length (depending upon your string source).

Related

how to extract two components from HEX string , reverse XOR

My I need to generate a random 32 char HEX string. I have code in place that will generate for example E272E28B8961FB155E3FC657831F0690
Now, I need to break this down into two 32 char strings such that value of string 1 XOR string 2 will = E272E28B8961FB155E3FC657831F0690
I seem to be having a hard time wrapping my head around that. I suppose I need a reverse XOR on this string. Any suggestions on how to accomplish this?
Assuming that you want two 32 Hexadecimal Character strings (which is equivalent to 16 bytes) which will XOR to a known 32 Hexadecimal Character string, you can use this method.
Generate random bytes for the first part of the output, then calculate what the second part has to be based on the first part and the expected output. XOR is a self-inverting operator (there's a fancy word for that that I'm forgetting) so it's fairly straightforward to do.
void q50415070()
{
var random = new Random();
var output = new byte[16];
random.NextBytes(output);
Debug.WriteLine(BitConverter.ToString(output));
// 91-77-E9-2F-EC-F7-8E-CC-03-AF-37-FD-4F-6F-D2-4D
var part1 = new byte[16];
random.NextBytes(part1);
Debug.WriteLine(BitConverter.ToString(part1));
// 7A-9B-2B-8B-D7-CE-AA-7E-7E-C3-FE-FF-44-2A-21-3C
var part2 = part1.Zip(output, (x, y) => (byte)(x ^ y)).ToArray();
Debug.WriteLine(BitConverter.ToString(part2));
// EB-EC-C2-A4-3B-39-24-B2-7D-6C-C9-02-0B-45-F3-71
}
In this, output is the result I'm trying to reach, and part1 and part2 are the two components that I want to be able to XOR together to get the expected output.
I've used the Linq Zip method to combine the two IEnumerable<byte>s together element by element, then used the XOR operator ^ to calculate the result byte-by-byte. Finally calling ToArray() to make it back into an array at the end.
This technique is used often in cryptography where you want to split an encryption key into two parts for two people to have, each of which is useless by itself.
Edit: Tweaked the function slightly to more closely match your question:
void q50415070()
{
var output = new byte[16] { 0xE2, 0x72, 0xE2, 0x8B, 0x89, 0x61, 0xFB, 0x15, 0x5E, 0x3F, 0xC6, 0x57, 0x83, 0x1F, 0x06, 0x90 };
Debug.WriteLine(BitConverter.ToString(output));
// E2-72-E2-8B-89-61-FB-15-5E-3F-C6-57-83-1F-06-90
var random = new Random();
var part1 = new byte[16];
random.NextBytes(part1);
Debug.WriteLine(BitConverter.ToString(part1));
// 59-37-D0-A6-71-CC-6C-17-96-02-70-CE-A7-57-06-25
var part2 = part1.Zip(output, (x, y) => (byte)(x ^ y)).ToArray();
Debug.WriteLine(BitConverter.ToString(part2));
// BB-45-32-2D-F8-AD-97-02-C8-3D-B6-99-24-48-00-B5
}
Hope this helps

How to decode an utf8 encoded string split in two buffers right in between a 4 byte long char?

A character in UTF8 encoding has up to 4 bytes. Now imagine I read from a stream into one buffer and then into the another. Unfortunately it just happens to be that at the end of the first buffer 2 chars of the 4 byte UTF8 encoded char are left and at the beginning of the the second buffer the rest 2 bytes.
Is there a way to partially decode that string (while leaving the 2 rest byte) without copying those two buffers into one big
string str = "Hello\u263AWorld";
Console.WriteLine(str);
Console.WriteLine("Length of 'HelloWorld': " + Encoding.UTF8.GetBytes("HelloWorld").Length);
var bytes = Encoding.UTF8.GetBytes(str);
Console.WriteLine("Length of 'Hello\u263AWorld': " + bytes.Length);
Console.WriteLine(Encoding.UTF8.GetString(bytes, 0, 6));
Console.WriteLine(Encoding.UTF8.GetString(bytes, 7, bytes.Length - 7));
This returns:
Hello☺World
Length of 'HelloWorld': 10
Length of 'Hello☺World': 13
Hello�
�World
The smiley face is 3 bytes long.
Is there a class that deals with split decoding of strings?
I would like to get first "Hello" and then "☺World" reusing the reminder of the not encoded byte array. Without copying both arrays into one big array. I really just want to use the reminder of the first buffer and somehow make the magic happen.
You should use a Decoder, which is able to maintain state between calls to GetChars - it remembers the bytes it hasn't decoded yet.
using System;
using System.Text;
class Test
{
static void Main()
{
string str = "Hello\u263AWorld";
var bytes = Encoding.UTF8.GetBytes(str);
var decoder = Encoding.UTF8.GetDecoder();
// Long enough for the whole string
char[] buffer = new char[100];
// Convert the first "packet"
var length1 = decoder.GetChars(bytes, 0, 6, buffer, 0);
// Convert the second "packet", writing into the buffer
// from where we left off
// Note: 6 not 7, because otherwise we're skipping a byte...
var length2 = decoder.GetChars(bytes, 6, bytes.Length - 6,
buffer, length1);
var reconstituted = new string(buffer, 0, length1 + length2);
Console.WriteLine(str == reconstituted); // true
}
}

How to add multiple bytes and get a byte array?

Given a byte array
byte[] someBytes = { 0xFF, 0xFE, 0xFE, 0xFF, 0x11, 0x00 ,0x00 ,0x00 ,0x00}
What's the best to add up all the bytes? Manually adding all of the bytes by hand as hex numbers would yield 40B on my above example so preferably I'd like to end up with something like:
byte[] byteSum = { 0x04, 0x0B }
Actually, all I really need is the 0x0B part (Used for checksum). Checksum is calculated by 0x0B XOR 0x55 (Which yields 0x5E) in this case.
I understand this isn't a normal addition of bytes, but this is how the checksum is calculated.
Manually looping through the byte array and adding them results in an integer sum.
What's the most concise way of doing this?
erm,
byte checksum;
foreach (var b in someBytes)
{
checksum = (byte)((checksum + b) & 0xff);
}
I'm not sure if I understand your question... But this is how I would do it:
byte sum = 0;
foreach (byte b in someBytes)
{
unchecked
{
sum += b;
}
}
But this does not yield 0x0B, but 0x69.
Using LINQ's sum and casting to byte in the end:
unchecked
{
var checksum = (byte)(someBytes.Sum(b => (long)b) ^ 0x55);
}

Converting int value into 3 byte array (and vice versa)

I am working on a C# WinForms application that reads/writes data to/from a hardware device. My application has a multiselect listbox which contains the numbers 1 - 100000 and the user may select up to 10 numbers. When they're done selecting each number, the user clicks a button and my event handler code needs to build a fixed-size (30 bytes) byte array using 3 bytes to represent each selected number and pad the array if less than 10 numbers were selected.
As an example, suppose my user chooses the following values:
17
99152
3064
52588
65536
I'm currently using this code to convert each number into a byte array:
byte[] bytes = BitConverter.GetBytes(selectedNumber);
Array.Reverse(bytes) // because BitConverter.IsLittleEndian() = true
Debug.WriteLine(BitConverter.ToString(bytes));
For the numbers I listed above, this produces the following:
00-00-00-11
00-01-83-50
00-00-0B-F8
00-00-CD-6C
00-01-00-00
BitConverter is giving me back a 4 byte array where I only have space to use 3 bytes to store each number in the final byte array. I can drop the most significant byte of each individual byte array and then build my final array like this:
00-00-11-01-83-50-00-0B-F8-00-CD-6C-01-00-00-[padding here]
Writing that to the device should work. But reading the array (or a similar array) back from the device causes a bit of a problem for me. When I have a 3 byte array and try to convert that into an int using this code...
int i = BitConverter.ToInt32(bytes, 0);
...I get "Destination array is not long enough to copy all the items in the collection." I suppose I could insert a most significant byte of 0x00 at the beginning of every three bytes and then convert that but is there a better way to do this?
I would imagine bit shifting and the | operator should be the most efficient way of doing this.
int i = (bytes[2] << 0) | (bytes[1] << 8) | (bytes[0] << 16);
Also, as a heads up, you're dropping the most significant byte, not the least significant byte ;p
byte[] bytes = new byte[] { 0x00, 0x00, 0x11, 0x01, 0x83, 0x50, 0x00, 0x0B, 0xF8 };
var ints = bytes.Select((b, i) => new { b, i })
.GroupBy(x => x.i / 3)
.Select(g => BitConverter.ToInt32(
new byte[] { 0 }.Concat(g.Select(x => x.b))
.Reverse()
.ToArray(),
0))
.ToArray();
or classically
var ints = new List<int>();
for (int i = 0; i < bytes.Length; i+=3)
{
int intI=0;
for (int j = i; j < i + 3; j++)
{
intI = intI * 256 + bytes[j]; //or (intI << 8) + bytes[j];
}
ints.Add(intI);
}
ints will be 17, 99152 and 3064

Integer to byte with given number of bits set

I don't know what to call this, which makes googling harder.
I have an integer, say 3, and want to convert it to 11100000, that is, a byte with the value of the integers number of bits set, from the most significantly bit.
I guess it could be done with:
byte result = 0;
for(int i = 8; i > 8 - 3; i--)
result += 2 ^ i;
but is there anything faster / more nice or, preferably, standard library included in .net?
int n = 3; // 0..8
int mask = 0xFF00;
byte result = (byte) (mask >> n);
Because there are only a few possibilities, you could just cache them:
// Each index adds another bit from the left, e.g. resultCache[3] == 11100000.
byte[] resultCache = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0XF8, 0xFC, 0xFE, 0xFF };
You'd also get an exception instead of a silent error if you accidentally tried to get the value for n > 8.

Categories