Convert bool[] to byte[] - c#

I have a List<bool> which I want to convert to a byte[]. How do i do this?
list.toArray() creates a bool[].

Here's two approaches, depending on whether you want to pack the bits into bytes, or have as many bytes as original bits:
bool[] bools = { true, false, true, false, false, true, false, true,
true };
// basic - same count
byte[] arr1 = Array.ConvertAll(bools, b => b ? (byte)1 : (byte)0);
// pack (in this case, using the first bool as the lsb - if you want
// the first bool as the msb, reverse things ;-p)
int bytes = bools.Length / 8;
if ((bools.Length % 8) != 0) bytes++;
byte[] arr2 = new byte[bytes];
int bitIndex = 0, byteIndex = 0;
for (int i = 0; i < bools.Length; i++)
{
if (bools[i])
{
arr2[byteIndex] |= (byte)(((byte)1) << bitIndex);
}
bitIndex++;
if (bitIndex == 8)
{
bitIndex = 0;
byteIndex++;
}
}

Marc's answer is good already, but...
Assuming you are the kind of person that is comfortable doing bit-twiddling, or just want to write less code and squeeze out some more performance, then this here code is for you good sir / madame:
byte[] PackBoolsInByteArray(bool[] bools)
{
int len = bools.Length;
int bytes = len >> 3;
if ((len & 0x07) != 0) ++bytes;
byte[] arr2 = new byte[bytes];
for (int i = 0; i < bools.Length; i++)
{
if (bools[i])
arr2[i >> 3] |= (byte)(1 << (i & 0x07));
}
}
It does the exact same thing as Marc's code, it's just more succinct.
Of course if we really want to go all out we could unroll it too...
...and while we are at it lets throw in a curve ball on the return type!
IEnumerable<byte> PackBoolsInByteEnumerable(bool[] bools)
{
int len = bools.Length;
int rem = len & 0x07; // hint: rem = len % 8.
/*
byte[] byteArr = rem == 0 // length is a multiple of 8? (no remainder?)
? new byte[len >> 3] // -yes-
: new byte[(len >> 3)+ 1]; // -no-
*/
const byte BZ = 0,
B0 = 1 << 0, B1 = 1 << 1, B2 = 1 << 2, B3 = 1 << 3,
B4 = 1 << 4, B5 = 1 << 5, B6 = 1 << 6, B7 = 1 << 7;
byte b;
int i = 0;
for (int mul = len & ~0x07; i < mul; i += 8) // hint: len = mul + rem.
{
b = bools[i] ? B0 : BZ;
if (bools[i + 1]) b |= B1;
if (bools[i + 2]) b |= B2;
if (bools[i + 3]) b |= B3;
if (bools[i + 4]) b |= B4;
if (bools[i + 5]) b |= B5;
if (bools[i + 6]) b |= B6;
if (bools[i + 7]) b |= B7;
//byteArr[i >> 3] = b;
yield return b;
}
if (rem != 0) // take care of the remainder...
{
b = bools[i] ? B0 : BZ; // (there is at least one more bool.)
switch (rem) // rem is [1:7] (fall-through switch!)
{
case 7:
if (bools[i + 6]) b |= B6;
goto case 6;
case 6:
if (bools[i + 5]) b |= B5;
goto case 5;
case 5:
if (bools[i + 4]) b |= B4;
goto case 4;
case 4:
if (bools[i + 3]) b |= B3;
goto case 3;
case 3:
if (bools[i + 2]) b |= B2;
goto case 2;
case 2:
if (bools[i + 1]) b |= B1;
break;
// case 1 is the statement above the switch!
}
//byteArr[i >> 3] = b; // write the last byte to the array.
yield return b; // yield the last byte.
}
//return byteArr;
}
Tip: As you can see I included the code for returning a byte[] as comments. Simply comment out the two yield statements instead if that is what you want/need.
Twiddling Hints:
Shifting x >> 3 is a cheaper x / 8.
Masking x & 0x07 is a cheaper x % 8.
Masking x & ~0x07 is a cheaper x - x % 8.
Edit:
Here is some example documentation:
/// <summary>
/// Bit-packs an array of booleans into bytes, one bit per boolean.
/// </summary><remarks>
/// Booleans are bit-packed into bytes, in order, from least significant
/// bit to most significant bit of each byte.<br/>
/// If the length of the input array isn't a multiple of eight, then one
/// or more of the most significant bits in the last byte returned will
/// be unused. Unused bits are zero / unset.
/// </remarks>
/// <param name="bools">An array of booleans to pack into bytes.</param>
/// <returns>
/// An IEnumerable<byte> of bytes each containing (up to) eight
/// bit-packed booleans.
/// </returns>

You can use LINQ. This won't be efficient, but will be simple. I'm assuming that you want one byte per bool.
bool[] a = new bool[] { true, false, true, true, false, true };
byte[] b = (from x in a select x ? (byte)0x1 : (byte)0x0).ToArray();

Or the IEnumerable approach to AnorZaken's answer:
static IEnumerable<byte> PackBools(IEnumerable<bool> bools)
{
int bitIndex = 0;
byte currentByte = 0;
foreach (bool val in bools) {
if (val)
currentByte |= (byte)(1 << bitIndex);
if (++bitIndex == 8) {
yield return currentByte;
bitIndex = 0;
currentByte = 0;
}
}
if (bitIndex != 8) {
yield return currentByte;
}
}
And the according unpacking where paddingEnd means the amount of bits to discard from the last byte to unpack:
static IEnumerable<bool> UnpackBools(IEnumerable<byte> bytes, int paddingEnd = 0)
{
using (var enumerator = bytes.GetEnumerator()) {
bool last = !enumerator.MoveNext();
while (!last) {
byte current = enumerator.Current;
last = !enumerator.MoveNext();
for (int i = 0; i < 8 - (last ? paddingEnd : 0); i++) {
yield return (current & (1 << i)) != 0;
}
}
}
}

If you have any control over the type of list, try to make it a List, which will then produce the byte[] on ToArray(). If you have an ArrayList, you can use:
(byte[])list.ToArray(typeof(byte));
To get the List, you could create one with your unspecified list iterator as an input to the constructor, and then produce the ToArray()? Or copy each item, casting to a new byte from bool?
Some info on what type of list it is might help.

Have a look at the BitConverter class. Depending on the exact nature of your requirement, it may solve your problem quite neatly.

Another LINQ approach, less effective than #hfcs101's but would easily work for other value types as well:
var a = new [] { true, false, true, true, false, true };
byte[] b = a.Select(BitConverter.GetBytes).SelectMany(x => x).ToArray();

Related

fast way to convert integer array to byte array (11 bit)

I have integer array and I need to convert it to byte array
but I need to take (only and just only) first 11 bit of each element of the هinteger array
and then convert it to a byte array
I tried this code
// ***********convert integer values to byte values
//***********to avoid the left zero padding on the byte array
// *********** first step : convert to binary string
// ***********second step : convert binary string to byte array
// *********** first step
string ByteString = Convert.ToString(IntArray[0], 2).PadLeft(11,'0');
for (int i = 1; i < IntArray.Length; i++)
ByteString = ByteString + Convert.ToString(IntArray[i], 2).PadLeft(11, '0');
// ***********second step
int numOfBytes = ByteString.Length / 8;
byte[] bytes = new byte[numOfBytes];
for (int i = 0; i < numOfBytes; ++i)
{
bytes[i] = Convert.ToByte(ByteString.Substring(8 * i, 8), 2);
}
But it takes too long time (if the file size large , the code takes more than 1 minute)
I need a very very fast code (very few milliseconds only )
can any one help me ?
Basically, you're going to be doing a lot of shifting and masking. The exact nature of that depends on the layout you want. If we assume that we pack little-endian from each int, appending on the left, so two 11-bit integers with positions:
abcdefghijk lmnopqrstuv
become the 8-bit chunks:
defghijk rstuvabc 00lmnopq
(i.e. take the lowest 8 bits of the first integer, which leaves 3 left over, so pack those into the low 3 bits of the next byte, then take the lowest 5 bits of the second integer, then finally the remaining 6 bits, padding with zero), then something like this should work:
using System;
using System.Linq;
static class Program
{
static string AsBinary(int val) => Convert.ToString(val, 2).PadLeft(11, '0');
static string AsBinary(byte val) => Convert.ToString(val, 2).PadLeft(8, '0');
static void Main()
{
int[] source = new int[1432];
var rand = new Random(123456);
for (int i = 0; i < source.Length; i++)
source[i] = rand.Next(0, 2047); // 11 bits
// Console.WriteLine(string.Join(" ", source.Take(5).Select(AsBinary)));
var raw = Encode(source);
// Console.WriteLine(string.Join(" ", raw.Take(6).Select(AsBinary)));
var clone = Decode(raw);
// now prove that it worked OK
if (source.Length != clone.Length)
{
Console.WriteLine($"Length: {source.Length} vs {clone.Length}");
}
else
{
int failCount = 0;
for (int i = 0; i < source.Length; i++)
{
if (source[i] != clone[i] && failCount++ == 0)
{
Console.WriteLine($"{i}: {source[i]} vs {clone[i]}");
}
}
Console.WriteLine($"Errors: {failCount}");
}
}
static byte[] Encode(int[] source)
{
long bits = source.Length * 11;
int len = (int)(bits / 8);
if ((bits % 8) != 0) len++;
byte[] arr = new byte[len];
int bitOffset = 0, index = 0;
for (int i = 0; i < source.Length; i++)
{
// note: this encodes little-endian
int val = source[i] & 2047;
int bitsLeft = 11;
if(bitOffset != 0)
{
val = val << bitOffset;
arr[index++] |= (byte)val;
bitsLeft -= (8 - bitOffset);
val >>= 8;
}
if(bitsLeft >= 8)
{
arr[index++] = (byte)val;
bitsLeft -= 8;
val >>= 8;
}
if(bitsLeft != 0)
{
arr[index] = (byte)val;
}
bitOffset = bitsLeft;
}
return arr;
}
private static int[] Decode(byte[] source)
{
int bits = source.Length * 8;
int len = (int)(bits / 11);
// note no need to worry about remaining chunks - no ambiguity since 11 > 8
int[] arr = new int[len];
int bitOffset = 0, index = 0;
for(int i = 0; i < source.Length; i++)
{
int val = source[i] << bitOffset;
int bitsLeftInVal = 11 - bitOffset;
if(bitsLeftInVal > 8)
{
arr[index] |= val;
bitOffset += 8;
}
else if(bitsLeftInVal == 8)
{
arr[index++] |= val;
bitOffset = 0;
}
else
{
arr[index++] |= (val & 2047);
if(index != arr.Length) arr[index] = val >> 11;
bitOffset = 8 - bitsLeftInVal;
}
}
return arr;
}
}
If you need a different layout you'll need to tweak it.
This encodes 512 MiB in just over a second on my machine.
Overview to the Encode method:
The first thing is does is pre-calculate the amount of space that is going to be required, and allocate the output buffer; since each input contributes 11 bits to the output, this is just some modulo math:
long bits = source.Length * 11;
int len = (int)(bits / 8);
if ((bits % 8) != 0) len++;
byte[] arr = new byte[len];
We know the output position won't match the input, and we know we're going to be starting each 11-bit chunk at different positions in bytes each time, so allocate variables for those, and loop over the input:
int bitOffset = 0, index = 0;
for (int i = 0; i < source.Length; i++)
{
...
}
return arr;
So: taking each input in turn (where the input is the value at position i), take the low 11 bits of the value - and observe that we have 11 bits (of this value) still to write:
int val = source[i] & 2047;
int bitsLeft = 11;
Now, if the current output value is partially written (i.e. bitOffset != 0), we should deal with that first. The amount of space left in the current output is 8 - bitOffset. Since we always have 11 input bits we don't need to worry about having more space than values to fill, so: left-shift our value by bitOffset (pads on the right with bitOffset zeros, as a binary operation), and "or" the lowest 8 bits of this with the output byte. Essentially this says "if bitOffset is 3, write the 5 low bits of val into the 5 high bits of the output buffer"; finally, fixup the values: increment our write position, record that we have fewer bits of the current value still to write, and use right-shift to discard the 8 low bits of val (which is made of bitOffset zeros and 8 - bitOffset "real" bits):
if(bitOffset != 0)
{
val = val << bitOffset;
arr[index++] |= (byte)val;
bitsLeft -= (8 - bitOffset);
val >>= 8;
}
The next question is: do we have (at least) an entire byte of data left? We might not, if bitOffset was 1 for example (so we'll have written 7 bits already, leaving just 4). If we do, we can just stamp that down and increment the write position - then once again track how many are left and throw away the low 8 bits:
if(bitsLeft >= 8)
{
arr[index++] = (byte)val;
bitsLeft -= 8;
val >>= 8;
}
And it is possible that we've still got some left-over; for example, if bitOffset was 7 we'll have written 1 bit in the first chunk, 8 bits in the second, leaving 2 more to write - or if bitOffset was 0 we won't have written anything in the first chunk, 8 in the second, leaving 3 left to write. So, stamp down whatever is left, but do not increment the write position - we've written to the low bits, but the next value might need to write to the high bits. Finally, update bitOffset to be however many low bits we wrote in the last step (which could be zero):
if(bitsLeft != 0)
{
arr[index] = (byte)val;
}
bitOffset = bitsLeft;
The Decode operation is the reverse of this logic - again, calculate the sizes and prepare the state:
int bits = source.Length * 8;
int len = (int)(bits / 11);
int[] arr = new int[len];
int bitOffset = 0, index = 0;
Now loop over the input:
for(int i = 0; i < source.Length; i++)
{
...
}
return arr;
Now, bitOffset is the start position that we want to write to in the current 11-bit value, so if we start at the start, it will be 0 on the first byte, then 8; 3 bits of the second byte join with the first 11-bit integer, so the 5 bits become part of the second - so bitOffset is 5 on the 3rd byte, etc. We can calculate the number of bits left in the current integer by subtracting from 11:
int val = source[i] << bitOffset;
int bitsLeftInVal = 11 - bitOffset;
Now we have 3 possible scenarios:
1) if we have more than 8 bits left in the current value, we can stamp down our input (as a bitwise "or") but do not increment the write position (as we have more to write for this value), and note that we're 8-bits further along:
if(bitsLeftInVal > 8)
{
arr[index] |= val;
bitOffset += 8;
}
2) if we have exactly 8 bits left in the current value, we can stamp down our input (as a bitwise "or") and increment the write position; the next loop can start at zero:
else if(bitsLeftInVal == 8)
{
arr[index++] |= val;
bitOffset = 0;
}
3) otherwise, we have less than 8 bits left in the current value; so we need to write the first bitsLeftInVal bits to the current output position (incrementing the output position), and whatever is left to the next output position. Since we already left-shifted by bitOffset, what this really means is simply: stamp down (as a bitwise "or") the low 11 bits (val & 2047) to the current position, and whatever is left (val >> 11) to the next if that wouldn't exceed our output buffer (padding zeros). Then calculate our new bitOffset:
else
{
arr[index++] |= (val & 2047);
if(index != arr.Length) arr[index] = val >> 11;
bitOffset = 8 - bitsLeftInVal;
}
And that's basically it. Lots of bitwise operations - shifts (<< / >>), masks (&) and combinations (|).
If you wanted to store the least significant 11 bits of an int into two bytes such that the least significant byte has bits 1-8 inclusive and the most significant byte has 9-11:
int toStore = 123456789;
byte msb = (byte) ((toStore >> 8) & 7); //or 0b111
byte lsb = (byte) (toStore & 255); //or 0b11111111
To check this, 123456789 in binary is:
0b111010110111100110100010101
MMMLLLLLLLL
The bits above L are lsb, and have a value of 21, above M are msb and have a value of 5
Doing the work is the shift operator >> where all the binary digits are slid to the right 8 places (8 of them disappear from the right hand side - they're gone, into oblivion):
0b111010110111100110100010101 >> 8 =
0b1110101101111001101
And the mask operator & (the mask operator works by only keeping bits where, in each position, they're 1 in the value and also 1 in the mask) :
0b111010110111100110100010101 &
0b000000000000000000011111111 (255) =
0b000000000000000000000010101
If you're processing an int array, just do this in a loop:
byte[] bs = new byte[ intarray.Length*2 ];
for(int x = 0, b=0; x < intarray.Length; x++){
int toStore = intarray[x];
bs[b++] = (byte) ((toStore >> 8) & 7);
bs[b++] = (byte) (toStore & 255);
}

Get, Set, Read, converts bitwise in Short type value in C#

I have a short value X:
short X=1; //Result in binary: 0000000000000001
I need to split them into an array and set the bits (say bit 6 and 10) //Result in binary: 0000001000100001
I need to convert it back to short X value.
How can I do it painlessly?
Could you please help?
1. Manual solution
Setting bit 6 and 10:
myValue |= (1 << 6)|(1 << 10);
Clearing bit 6 and 10:
myValue &= ~((1 << 6)|(1 << 10));
2. Use BitArray
var bits = new BitArray(16); // 16 bits
bits[5] = true;
bits[10] = true;
Convert back to short:
var raw = new byte[2];
bits.CopyTo(raw, 0);
var asShort = BitConverter.ToInt16(raw, 0);
If what you are referring to is a very basic encryption, then perhaps using the XOR (^) operator would be better suited for your needs.
short FlipBytes(short original, params int[] bytesToSet)
{
int key = 0;
foreach (int b in bytesToSet)
{
if (b >= 0 && b < 16)
{
key |= 1 << b;
}
}
return (short)(original ^ key);
}
This method will both set and reset the bytes that you desire. For example:
short X = 1;
short XEncrypt = FlipBytes(X, 6, 10);
short XDecrypt = FlipBytes(XEncrypt, 6, 10);
// X = 1 , Binary = 0000000000000001
// XEncrypt = 1089 , Binary = 0000010001000001
// XDecrypt = 1 , Binary = 0000000000000001
If you have a int value "intValue" and you want to set a specific bit at position "bitPosition", do something like:
intValue = intValue | (1 << bitPosition);
or shorter:
intValue |= 1 << bitPosition;
If you want to reset a bit (i.e, set it to zero), you can do this:
intValue &= ~(1 << bitPosition);
(The operator ~ reverses each bit in a value, thus ~(1 << bitPosition) will result in an int where every bit is 1 except the bit at the given bitPosition.)
Linq solution, terser, but probably, less readable than foreach loop:
using System.Linq;
...
short X = 1;
var bitsToSet = new[] { 5, 9 };
var result = X | bitsToSet.Aggregate((s, a) => s |= 1 << a);
If you insist on short add cast:
short result = (short) (X | bitsToSet.Aggregate((s, a) => s |= 1 << a));

C# CRC implementation

I am trying to integrate a Serial-port device into my application, which needs CRC-CCTT validation for the bytes that I send to it.
I'm kinda new into managing byte packets, and need help for this.
It uses this formula for making the CRC calculus:
[CRC-CCITT P(X)= X16 + C12 + C8 + 1]
So for example for the packet: 0xFC 0x05 0x11, the CRC is 0x5627.
Then I send this packet to the device: 0xFC 0x05 0x11 0x27 0x56
Also, packet lenghts will vary from 5 to 255 (including CRC checks bytes)
I don't know how to implement this, so any idea/suggestions will be welcome.
Hope I made myself clear,
Thanks in Advance.
EDIT:
here is the specification of what I need to do:
standard crc-ccitt is x16 + x12 + x5 + 1 I wrote the one # http://www.sanity-free.com/133/crc_16_ccitt_in_csharp.html If I have time I'll see if I can't modify it to run with the x16 + x12 + x8 + 1 poly.
EDIT:
here you go:
public class Crc16CcittKermit {
private static ushort[] table = {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};
public static ushort ComputeChecksum( params byte[] buffer ) {
if ( buffer == null ) throw new ArgumentNullException( );
ushort crc = 0;
for ( int i = 0; i < buffer.Length; ++i ) {
crc = (ushort)( ( crc >> 8 ) ^ table[( crc ^ buffer[i] ) & 0xff] );
}
return crc;
}
public static byte[] ComputeChecksumBytes( params byte[] buffer ) {
return BitConverter.GetBytes( ComputeChecksum( buffer ) );
}
}
sample:
ushort crc = Crc16CcittKermit.ComputeChecksum( 0xFC, 0x05, 0x11 );
byte[] crcBuffer = Crc16CcittKermit.ComputeChecksumBytes( 0xFC, 0x05, 0x11 )
// crc = 0x5627
// crcBuffer = { 0x27, 0x56 }
Have you tried Googling for an example? There are many of them.
Example 1: http://tomkaminski.com/crc32-hashalgorithm-c-net
Example 2: http://www.sanity-free.com/12/crc32_implementation_in_csharp.html
You also have native MD5 support in .Net through System.Security.Cryptography.MD5CryptoServiceProvider.
EDIT:
If you are looking for an 8-bit algorithm: http://www.codeproject.com/KB/cs/csRedundancyChckAlgorithm.aspx
And 16-bit: http://www.sanity-free.com/133/crc_16_ccitt_in_csharp.html
LOL, I've encountered exactly the same STATUS REQUEST sequense, i'm currently developing software to use with CashCode Bill Validator:). Here's the code worked for me, it's CRC16-CCITT with reversed polynomial equals 0x8408 (BDPConstants.Polynomial in the code). That's the code worked for me:
// TableCRC16Size is 256 of course, don't forget to set in somewhere
protected ushort[] TableCRC16 = new ushort[BDPConstants.TableCRC16Size];
protected void InitCRC16Table()
{
for (ushort i = 0; i < BDPConstants.TableCRC16Size; ++i)
{
ushort CRC = 0;
ushort c = i;
for (int j = 0; j < 8; ++j)
{
if (((CRC ^ c) & 0x0001) > 0)
CRC = (ushort)((CRC >> 1) ^ BDPConstants.Polynominal);
else
CRC = (ushort)(CRC >> 1);
c = (ushort)(c >> 1);
}
TableCRC16[i] = CRC;
}
}
protected ushort CalcCRC16(byte[] aData)
{
ushort CRC = 0;
for (int i = 0; i < aData.Length; ++i)
CRC = (ushort)(TableCRC16[(CRC ^ aData[i]) & 0xFF] ^ (CRC >> 8));
return CRC;
}
Initialize the table somewhere (e.g. Form constructor):
InitCRC16Table();
then use it in your code just like that,
You can use List of bytes instead of array, more convinient to pack byte data in the 'packet' for sending
uint CRC = CalcCRC16(byte[] aByte)
// You need to split your CRC in two bytes of course
byte CRCHW = (byte)((CRC) / 256); // that's your 0x56
byte CRCLW = (byte)(CRC); // that's your 0x27
it works and dose not need table:
/// <summary>
/// Gens the CRC16.
/// CRC-1021 = X(16)+x(12)+x(5)+1
/// </summary>
/// <param name="c">The c.</param>
/// <param name="nByte">The n byte.</param>
/// <returns>System.Byte[][].</returns>
public ushort GenCrc16(byte[] c, int nByte)
{
ushort Polynominal = 0x1021;
ushort InitValue = 0x0;
ushort i, j, index = 0;
ushort CRC = InitValue;
ushort Remainder, tmp, short_c;
for (i = 0; i < nByte; i++)
{
short_c = (ushort)(0x00ff & (ushort) c[index]);
tmp = (ushort)((CRC >> 8) ^ short_c);
Remainder = (ushort)(tmp << 8);
for (j = 0; j < 8; j++)
{
if ((Remainder & 0x8000) != 0)
{
Remainder = (ushort)((Remainder << 1) ^ Polynominal);
}
else
{
Remainder = (ushort)(Remainder << 1);
}
}
CRC = (ushort)((CRC << 8) ^ Remainder);
index++;
}
return CRC;
}
You are actually using CRC-XMODEM LSB-reverse (with 0x8408 coefficient). C# code for this calculus is:
public void crc_bytes(int[] int_input)
{
int_array = int_input;
int int_crc = 0x0; // or 0xFFFF;
int int_lsb;
for (int int_i = 0; int_i < int_array.Length; int_i++)
{
int_crc = int_crc ^ int_array[int_i];
for (int int_j = 0; int_j < 8; int_j ++ )
{
int_lsb = int_crc & 0x0001; // Mask of LSB
int_crc = int_crc >> 1;
int_crc = int_crc & 0x7FFF;
if (int_lsb == 1)
int_crc = int_crc ^ 0x8408;
}
}
int_crc_byte_a = int_crc & 0x00FF;
int_crc_byte_b = (int_crc >> 8) & 0x00FF;
}
Read more (or download project):
http://www.cirvirlab.com/index.php/c-sharp-code-examples/141-c-sharp-crc-computation.html

Fastest way to calculate sum of bits in byte array

I have two byte arrays with the same length. I need to perform XOR operation between each byte and after this calculate sum of bits.
For example:
11110000^01010101 = 10100101 -> so 1+1+1+1 = 4
I need do the same operation for each element in byte array.
Use a lookup table. There are only 256 possible values after XORing, so it's not exactly going to take a long time. Unlike izb's solution though, I wouldn't suggest manually putting all the values in though - compute the lookup table once at startup using one of the looping answers.
For example:
public static class ByteArrayHelpers
{
private static readonly int[] LookupTable =
Enumerable.Range(0, 256).Select(CountBits).ToArray();
private static int CountBits(int value)
{
int count = 0;
for (int i=0; i < 8; i++)
{
count += (value >> i) & 1;
}
return count;
}
public static int CountBitsAfterXor(byte[] array)
{
int xor = 0;
foreach (byte b in array)
{
xor ^= b;
}
return LookupTable[xor];
}
}
(You could make it an extension method if you really wanted...)
Note the use of byte[] in the CountBitsAfterXor method - you could make it an IEnumerable<byte> for more generality, but iterating over an array (which is known to be an array at compile-time) will be faster. Probably only microscopically faster, but hey, you asked for the fastest way :)
I would almost certainly actually express it as
public static int CountBitsAfterXor(IEnumerable<byte> data)
in real life, but see which works better for you.
Also note the type of the xor variable as an int. In fact, there's no XOR operator defined for byte values, and if you made xor a byte it would still compile due to the nature of compound assignment operators, but it would be performing a cast on each iteration - at least in the IL. It's quite possible that the JIT would take care of this, but there's no need to even ask it to :)
Fastest way would probably be a 256-element lookup table...
int[] lut
{
/*0x00*/ 0,
/*0x01*/ 1,
/*0x02*/ 1,
/*0x03*/ 2
...
/*0xFE*/ 7,
/*0xFF*/ 8
}
e.g.
11110000^01010101 = 10100101 -> lut[165] == 4
This is more commonly referred to as bit counting. There are literally dozens of different algorithms for doing this. Here is one site which lists a few of the more well known methods. There are even CPU specific instructions for doing this.
Theorectically, Microsoft could add a BitArray.CountSetBits function that gets JITed with the best algorithm for that CPU architecture. I, for one, would welcome such an addition.
As I understood it you want to sum the bits of each XOR between the left and right bytes.
for (int b = 0; b < left.Length; b++) {
int num = left[b] ^ right[b];
int sum = 0;
for (int i = 0; i < 8; i++) {
sum += (num >> i) & 1;
}
// do something with sum maybe?
}
I'm not sure if you mean sum the bytes or the bits.
To sum the bits within a byte, this should work:
int nSum = 0;
for (int i=0; i<=7; i++)
{
nSum += (byte_val>>i) & 1;
}
You would then need the xoring, and array looping around this, of course.
The following should do
int BitXorAndSum(byte[] left, byte[] right) {
int sum = 0;
for ( var i = 0; i < left.Length; i++) {
sum += SumBits((byte)(left[i] ^ right[i]));
}
return sum;
}
int SumBits(byte b) {
var sum = 0;
for (var i = 0; i < 8; i++) {
sum += (0x1) & (b >> i);
}
return sum;
}
It can be rewritten as ulong and use unsafe pointer, but byte is easier to understand:
static int BitCount(byte num)
{
// 0x5 = 0101 (bit) 0x55 = 01010101
// 0x3 = 0011 (bit) 0x33 = 00110011
// 0xF = 1111 (bit) 0x0F = 00001111
uint count = num;
count = ((count >> 1) & 0x55) + (count & 0x55);
count = ((count >> 2) & 0x33) + (count & 0x33);
count = ((count >> 4) & 0xF0) + (count & 0x0F);
return (int)count;
}
A general function to count bits could look like:
int Count1(byte[] a)
{
int count = 0;
for (int i = 0; i < a.Length; i++)
{
byte b = a[i];
while (b != 0)
{
count++;
b = (byte)((int)b & (int)(b - 1));
}
}
return count;
}
The less 1-bits, the faster this works. It simply loops over each byte, and toggles the lowest 1 bit of that byte until the byte becomes 0. The castings are necessary so that the compiler stops complaining about the type widening and narrowing.
Your problem could then be solved by using this:
int Count1Xor(byte[] a1, byte[] a2)
{
int count = 0;
for (int i = 0; i < Math.Min(a1.Length, a2.Length); i++)
{
byte b = (byte)((int)a1[i] ^ (int)a2[i]);
while (b != 0)
{
count++;
b = (byte)((int)b & (int)(b - 1));
}
}
return count;
}
A lookup table should be the fastest, but if you want to do it without a lookup table, this will work for bytes in just 10 operations.
public static int BitCount(byte value) {
int v = value - ((value >> 1) & 0x55);
v = (v & 0x33) + ((v >> 2) & 0x33);
return ((v + (v >> 4) & 0x0F));
}
This is a byte version of the general bit counting function described at Sean Eron Anderson's bit fiddling site.

Convert from BitArray to Byte

I have a BitArray with the length of 8, and I need a function to convert it to a byte. How to do it?
Specifically, I need a correct function of ConvertToByte:
BitArray bit = new BitArray(new bool[]
{
false, false, false, false,
false, false, false, true
});
//How to write ConvertToByte
byte myByte = ConvertToByte(bit);
var recoveredBit = new BitArray(new[] { myByte });
Assert.AreEqual(bit, recoveredBit);
This should work:
byte ConvertToByte(BitArray bits)
{
if (bits.Count != 8)
{
throw new ArgumentException("bits");
}
byte[] bytes = new byte[1];
bits.CopyTo(bytes, 0);
return bytes[0];
}
A bit late post, but this works for me:
public static byte[] BitArrayToByteArray(BitArray bits)
{
byte[] ret = new byte[(bits.Length - 1) / 8 + 1];
bits.CopyTo(ret, 0);
return ret;
}
Works with:
string text = "Test";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(text);
BitArray bits = new BitArray(bytes);
bytes[] bytesBack = BitArrayToByteArray(bits);
string textBack = System.Text.Encoding.ASCII.GetString(bytesBack);
// bytes == bytesBack
// text = textBack
.
A poor man's solution:
protected byte ConvertToByte(BitArray bits)
{
if (bits.Count != 8)
{
throw new ArgumentException("illegal number of bits");
}
byte b = 0;
if (bits.Get(7)) b++;
if (bits.Get(6)) b += 2;
if (bits.Get(5)) b += 4;
if (bits.Get(4)) b += 8;
if (bits.Get(3)) b += 16;
if (bits.Get(2)) b += 32;
if (bits.Get(1)) b += 64;
if (bits.Get(0)) b += 128;
return b;
}
Unfortunately, the BitArray class is partially implemented in .Net Core class (UWP). For example BitArray class is unable to call the CopyTo() and Count() methods. I wrote this extension to fill the gap:
public static IEnumerable<byte> ToBytes(this BitArray bits, bool MSB = false)
{
int bitCount = 7;
int outByte = 0;
foreach (bool bitValue in bits)
{
if (bitValue)
outByte |= MSB ? 1 << bitCount : 1 << (7 - bitCount);
if (bitCount == 0)
{
yield return (byte) outByte;
bitCount = 8;
outByte = 0;
}
bitCount--;
}
// Last partially decoded byte
if (bitCount < 7)
yield return (byte) outByte;
}
The method decodes the BitArray to a byte array using LSB (Less Significant Byte) logic. This is the same logic used by the BitArray class. Calling the method with the MSB parameter set on true will produce a MSB decoded byte sequence. In this case, remember that you maybe also need to reverse the final output byte collection.
This should do the trick. However the previous answer is quite likely the better option.
public byte ConvertToByte(BitArray bits)
{
if (bits.Count > 8)
throw new ArgumentException("ConvertToByte can only work with a BitArray containing a maximum of 8 values");
byte result = 0;
for (byte i = 0; i < bits.Count; i++)
{
if (bits[i])
result |= (byte)(1 << i);
}
return result;
}
In the example you posted the resulting byte will be 0x80. In other words the first value in the BitArray coresponds to the first bit in the returned byte.
That's should be the ultimate one. Works with any length of array.
private List<byte> BoolList2ByteList(List<bool> values)
{
List<byte> ret = new List<byte>();
int count = 0;
byte currentByte = 0;
foreach (bool b in values)
{
if (b) currentByte |= (byte)(1 << count);
count++;
if (count == 7) { ret.Add(currentByte); currentByte = 0; count = 0; };
}
if (count < 7) ret.Add(currentByte);
return ret;
}
In addition to #JonSkeet's answer you can use an Extension Method as below:
public static byte ToByte(this BitArray bits)
{
if (bits.Count != 8)
{
throw new ArgumentException("bits");
}
byte[] bytes = new byte[1];
bits.CopyTo(bytes, 0);
return bytes[0];
}
And use like:
BitArray foo = new BitArray(new bool[]
{
false, false, false, false,false, false, false, true
});
foo.ToByte();
byte GetByte(BitArray input)
{
int len = input.Length;
if (len > 8)
len = 8;
int output = 0;
for (int i = 0; i < len; i++)
if (input.Get(i))
output += (1 << (len - 1 - i)); //this part depends on your system (Big/Little)
//output += (1 << i); //depends on system
return (byte)output;
}
Cheers!
Little endian byte array converter : First bit (indexed with "0") in the BitArray
assumed to represents least significant bit (rightmost bit in the bit-octet) which interpreted as "zero" or "one" as binary.
public static class BitArrayExtender {
public static byte[] ToByteArray( this BitArray bits ) {
const int BYTE = 8;
int length = ( bits.Count / BYTE ) + ( (bits.Count % BYTE == 0) ? 0 : 1 );
var bytes = new byte[ length ];
for ( int i = 0; i < bits.Length; i++ ) {
int bitIndex = i % BYTE;
int byteIndex = i / BYTE;
int mask = (bits[ i ] ? 1 : 0) << bitIndex;
bytes[ byteIndex ] |= (byte)mask;
}//for
return bytes;
}//ToByteArray
}//class

Categories