Represent a Guid as a set of integers - c#

If I want to represent a guid as a set of integers how would I handle the conversion? I'm thinking along the lines of getting the byte array representation of the guid and breaking it up into the fewest possible 32 bit integers that can be converted back into the original guid. Code examples preferred...
Also, what will the length of the resulting integer array be?

As a GUID is just 16 bytes, you can convert it to four integers:
Guid id = Guid.NewGuid();
byte[] bytes = id.ToByteArray();
int[] ints = new int[4];
for (int i = 0; i < 4; i++) {
ints[i] = BitConverter.ToInt32(bytes, i * 4);
}
Converting back is just getting the integers as byte arrays and put together:
byte[] bytes = new byte[16];
for (int i = 0; i < 4; i++) {
Array.Copy(BitConverter.GetBytes(ints[i]), 0, bytes, i * 4, 4);
}
Guid id = new Guid(bytes);

System.Guid guid = System.Guid.NewGuid();
byte[] guidArray = guid.ToByteArray();
// condition
System.Diagnostics.Debug.Assert(guidArray.Length % sizeof(int) == 0);
int[] intArray = new int[guidArray.Length / sizeof(int)];
System.Buffer.BlockCopy(guidArray, 0, intArray, 0, guidArray.Length);
byte[] guidOutArray = new byte[guidArray.Length];
System.Buffer.BlockCopy(intArray, 0, guidOutArray, 0, guidOutArray.Length);
System.Guid guidOut = new System.Guid(guidOutArray);
// check
System.Diagnostics.Debug.Assert(guidOut == guid);

Somehow I had much more fun doing it this way:
byte[] bytes = guid.ToByteArray();
int[] ints = new int[bytes.Length / sizeof(int)];
for (int i = 0; i < bytes.Length; i++) {
ints[i / sizeof(int)] = ints[i / sizeof(int)] | (bytes[i] << 8 * ((sizeof(int) - 1) - (i % sizeof(int))));
}
and converting back:
byte[] bytesAgain = new byte[ints.Length * sizeof(int)];
for (int i = 0; i < bytes.Length; i++) {
bytesAgain[i] = (byte)((ints[i / sizeof(int)] & (byte.MaxValue << 8 * ((sizeof(int) - 1) - (i % sizeof(int))))) >> 8 * ((sizeof(int) - 1) - (i % sizeof(int))));
}
Guid guid2 = new Guid(bytesAgain);

Will the build-in Guid structure not suffice?
Constructor:
public Guid(
byte[] b
)
And
public byte[] ToByteArray()
Which, returns a 16-element byte array that contains the value of this instance.
Packing the bytes into integers and visa versa should be trivial.

A Guid is typically just a 128-bit number.
-- Edit
So in C#, you can get the 16 bytes via
byte[] b = Guid.NewGuid().ToByteArray();

Related

How to convert from decimal to binary invert it with ~ and convert back to decimal

Not sure if I am in the right direction.
I can't find info about tilde.
int n = 5;
int m = ~n;
string numAsString = Convert.ToString(~n, 2);
char[] NumAsChar = numAsString.ToCharArray();
long l = Convert.ToInt64(numAsString, 2);
Console.WriteLine(numAsString);
Console.WriteLine(l);
You're probably looking for a simple answer.
int n = 5;
byte[] nbytes = BitConverter.GetBytes(n);
for(int i = 0 ; i < nbytes.Length; i++)
nbytes[i] = ~nbytes[i];
n = BitConverter.ToInt32(nbytes, 0);
edit: you actually can't do ~ on a byte[]. You can either do
for(int i = 0 ; i < nbytes.Length; i++)
nbytes[i] = ~nbytes[i];
or just not use a byte array at all.
For clarity's sake, do note that you can just do
n = ~n;
and skip doing any of the separation. But you specifically asked for the byte conversion.
Use these 2 methods
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
And then use them like this
byte[] bytes = GetTheBytes(str);
byte[] reversed = bytes.Reverse().ToArray();
var revStr = GetString(reversed)
I did it like this.Any suggestions on making it simpler.
int n = 100;
//Convert decimal to binary
string numAsString = Convert.ToString(n, 2);
char[] NumAsChar = numAsString.ToCharArray();
Console.WriteLine(numAsString);
//Invert bits
for (int i = 0; i < numAsString.Length; i++)
{
if (NumAsChar[i] == '0')
{
NumAsChar[i] = '1';
}
else
{
NumAsChar[i] = '0';
}
}
string NewNumAsString = new string(NumAsChar);
//Convert inverted binary num to decimal
long l = Convert.ToInt64(NewNumAsString, 2);
Console.WriteLine(NewNumAsString);
Console.WriteLine(l);

Calculate CRC 8 of data received on serial port c#

I am receiving data from serial port in an byte array
How can I calculate the checksum of the data not included the sync (54) and checksum (F2) byte and want to match with the last check sum byte.
Updated :
int bytes = comport.BytesToRead;
byte indexCRC;
int sumCRC = 0;
byte checksumCRC = 0;
byte checksum;
byte[] RXBuffer = new byte[bytes];
comport.Read(RXBuffer, 0, bytes);
checksum = RXBuffer.Last();
byte[] RXBufferCRC = new byte[bytes];
for (indexCRC = 1; indexCRC < RXBufferCRC.Length; indexCRC++)
{
sumCRC = sumCRC + RXBufferCRC[indexCRC];
}
checksumCRC = (byte)(sumCRC);
Start the index from 1 but before doing that delete the last index of the array and store the array in an other array something like that
int Secbytes = comport.BytesToRead;
byte[] SecRXBuffer = new byte[Secbytes];
Array.Copy(SecRXBuffer, VanguardConstants.RECEIVEINDEX, RXBuffer, 0, Secbytes);
byte[] tmp = new byte[bytes - 1];
Array.Copy(RXBuffer, tmp, Secbytes - 1);
for (i = 1; i < tmp.Length; i++)
{
Sum = (byte)(Sum + tmp[i]);
}
Checksum = ((byte)Sum);
http://err.se/crc8-for-ibutton-in-c/
Here is an implementation of a CRC8 function in C#.

String of bits to Unicode

I have a string of bits, like this string str = "0111001101101000" It's the letters"sh".
I need to make Unicode letters out of it. I'm doing following:
BitArray bn = new BitArray(str.Length); //creating new bitarray
for (int kat = 0; kat < str.Length; kat++)
{
if (str[kat].ToString() == "0")//adding boolean values into array
{
bn[kat] = false;
}
else
bn[kat] = true;
}
byte[] bytes = new byte[bn.Length];//converting to bytes
bn.CopyTo(bytes, 0);
string output = Encoding.Unicode.GetString(bytes); //encoding
textBox2.Text = output; // result in textbox
But the output text is just complete mess. How to do it right?
There's a couple of problems with your code.
First BitArray will reverse the bit order - it's easier to use
Convert.ToByte
Your input string contains two bytes (one
per character), but you're using Encoding.Unicode to decode it, which
is UTF16 encoding (two bytes per character), you need to use Encoding.UTF8
Working Code
string str = "0111001101101000";
int numOfBytes = str.Length / 8;
byte[] bytes = new byte[numOfBytes];
for (int i = 0; i < numOfBytes; ++i)
{
bytes[i] = Convert.ToByte(str.Substring(8 * i, 8), 2);
}
string output = Encoding.UTF8.GetString(bytes);
A) Your string is ASCII, not UNICODE: 8 bits per character
B) The most significant bit of every byte is on the left, so the strange math used in bn[...]
C) The commented part is useless because "false" is the default state of a BitArray
D) The length of the byte array was wrong. 8 bits == 1 byte! :-)
string str = "0111001101101000";
BitArray bn = new BitArray(str.Length); //creating new bitarray
for (int kat = 0; kat < str.Length; kat++) {
if (str[kat] == '0')//adding boolean values into array
{
//bn[(kat / 8 * 8) + 7 - (kat % 8)] = false;
} else {
bn[(kat / 8 * 8) + 7 - (kat % 8)] = true;
}
}
// 8 bits in a byte
byte[] bytes = new byte[bn.Length / 8];//converting to bytes
bn.CopyTo(bytes, 0);
string output = Encoding.ASCII.GetString(bytes); //encoding
Probably better:
string str = "0111001101101000";
byte[] bytes = new byte[str.Length / 8];
for (int ix = 0, weight = 128, ix2 = 0; ix < str.Length; ix++) {
if (str[ix] == '1') {
bytes[ix2] += (byte)weight;
}
weight /= 2;
// Every 8 bits we "reset" the weight
// and increment the ix2
if (weight == 0) {
ix2++;
weight = 128;
}
}
string output = Encoding.ASCII.GetString(bytes); //encoding

Fastest way to extract variable width signed integer from byte[]

The title speaks for itself. I have a file containing a base64 encoded byte[] of variable width integer, min 8 bit, max 32bit
I have a large file (48MB) and I am trying to find the fastest way of grabbing integers from the stream.
This is the fastest code from a perf app:
static int[] Base64ToIntArray3(string base64, int size)
{
List<int> res = new List<int>();
byte[] buffer = new byte[4];
using (var ms = new System.IO.MemoryStream(Convert.FromBase64String(base64)))
{
while(ms.Position < ms.Length)
{
ms.Read(buffer, 0, size);
res.Add(BitConverter.ToInt32(buffer, 0));
}
}
return res.ToArray();
}
I can't see a faster way of padding the bytes to 32bit. Any ideas, chaps and chapettes? Solutions should be in c#. I could fall down to C/++ if i must but i don't want to.
There is no reason to use a memory stream to move bytes from an array to another array, just read from the array directly. Also, the size of the array is known, so there is need to add the items to a list that is then converted to an array, you can use an array from the start:
static int[] Base64ToIntArray3(string base64, int size) {
byte[] data = Convert.FromBase64String(base64);
int cnt = data.Length / size;
int[] res = new int[cnt];
for (int i = 0; i < cnt; i++) {
switch (size) {
case 1: res[i] = data[i]; break;
case 2: res[i] = BitConverter.ToInt16(data, i * 2); break;
case 3: res[i] = data[i * 3] + data[i * 3 + 1] * 256 + data[i * 3 + 2] * 65536; break;
case 4: res[i] = BitConverter.ToInt32(data, i * 4); break;
}
}
return res;
}
Note: Untested code! You have to verify that it actually does what it is supposed to do, but at least it shows the principle.
This is probably how I would do it. Not using a stream should increase performance. This seems like the sort of thing that should be easy to do using Linq but I couldn't figure it out.
static int[] Base64ToIntArray3(string base64, int size)
{
if (size < 1 || size > 4) throw new ArgumentOutOfRangeException("size");
byte[] data = Convert.FromBase64String(base64);
List<int> res = new List<int>();
byte[] buffer = new byte[4];
for (int i = 0; i < data.Length; i += size )
{
Buffer.BlockCopy(data, i, buffer, 0, size);
res.Add(BitConverter.ToInt32(buffer, 0));
}
return res.ToArray();
}
Ok so I believe this is the Linq way to do this:
static int[] Base64ToIntArray3(string base64, int size)
{
byte[] data = Convert.FromBase64String(base64);
return data.Select((Value, Index) => new { Value, Index })
.GroupBy(p => p.Index / size)
.Select(g => BitConverter.ToInt32(g.Select(p => p.Value).Union(new byte[4 - size]).ToArray(), 0))
.ToArray();
}

Convert Byte Array to Bit Array?

How would I go about converting a bytearray to a bit array?
The obvious way; using the constructor that takes a byte array:
BitArray bits = new BitArray(arrayOfBytes);
It depends on what you mean by "bit array"... If you mean an instance of the BitArray class, Guffa's answer should work fine.
If you actually want an array of bits, in the form of a bool[] for instance, you could do something like that :
byte[] bytes = ...
bool[] bits = bytes.SelectMany(GetBits).ToArray();
...
IEnumerable<bool> GetBits(byte b)
{
for(int i = 0; i < 8; i++)
{
yield return (b & 0x80) != 0;
b *= 2;
}
}
public static byte[] ToByteArray(this BitArray bits)
{
int numBytes = bits.Count / 8;
if (bits.Count % 8 != 0) numBytes++;
byte[] bytes = new byte[numBytes];
int byteIndex = 0, bitIndex = 0;
for (int i = 0; i < bits.Count; i++) {
if (bits[i])
bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
bitIndex++;
if (bitIndex == 8) {
bitIndex = 0;
byteIndex++;
}
}
return bytes;
}
You can use BitArray to create a stream of bits from a byte array. Here an example:
string testMessage = "This is a test message";
byte[] messageBytes = Encoding.ASCII.GetBytes(testMessage);
BitArray messageBits = new BitArray(messageBytes);
byte number = 128;
Convert.ToString(number, 2);
=> out: 10000000
public static byte[] ToByteArray(bool[] byteArray)
{
return = byteArray
.Select(
(val1, idx1) => new { Index = idx1 / 8, Val = (byte)(val1 ? Math.Pow(2, idx1 % 8) : 0) }
)
.GroupBy(gb => gb.Index)
.Select(val2 => (byte)val2.Sum(s => (byte)s.Val))
.ToArray();
}

Categories

Resources