Try to calculate IP header checksum - c#

i try to write a function that calculate IP Header Checksum using this example.
So first i have my IP header bytes:
byte[] arr = {
69, 0, 0, 60, 28, 70, 64, 0, 64, 6,
0, 0, 172, 16, 10, 99, 172, 16, 10, 12
};
Here i am add all pairs of bytes:
public static ushort[] AddPairs(byte[] arr)
{
List<ushort> pairs = new List<ushort>();
for (int i = 0; i < arr.Length; i += 2)
{
byte b1 = arr[i];
byte b2 = arr[i + 1];
ushort add = (ushort)((arr[i] << 8) + arr[i + 1]);
pairs.Add(add);
}
return pairs.ToArray();
}
And here i need to calculate the Checksum:
public static void ComputeHeaderIpChecksum(byte[] arr)
{
ushort[] pairs = AddPairs(arr);
ushort result;
ushort tmp = 0;
for (int i = 0; i < pairs.Length; i++)
{
result = (ushort)(pairs[i] + pairs[i + 1]);
tmp = result;
}
}
So first after add 2 values how can i check if this is valid ushort without the carry ?
i am kind of stuck here and don't know what to do next and will glad for some help.

C code for checksum from microchip
WORD CalcIPChecksum(BYTE *buffer, WORD count)
{
// wordval = CalcIPChecksum(&pEEPROMbuf[0x0800 + 6], 51);
WORD i;
WORD *val;
union
{
WORD w[2];
DWORD dw;
} sum;
i = count >> 1;
val = (WORD *)buffer;
//unsigned char temp;
// Calculate the sum of all words
sum.dw = 0L;
while(i--)
{
//temp = *val;
sum.dw += (DWORD)*val++;
}
// Add in the sum of the remaining byte, if present
if (count & 0x1)
{
DWORD temp = (DWORD)*(BYTE *)val;
sum.dw += temp;
}
// Do an end-around carry (one's complement arrithmetic)
sum.dw = sum.w[0] + sum.w[1];
// Do another end-around carry in case if the prior add
// caused a carry out
sum.w[0] += sum.w[1];
WORD answer = ~sum.w[0];
// Return the resulting checksum
return ;
}
Same function in c#
private UInt16 CalcIPChecksum(byte[] buffer, ushort count,int offset)
{
ushort i =0;
byte[] val = StatMethods.memcpy(ref buffer, offset, count);// get_byte_arr(buffer, count, offset);
// public static byte[] memcpy(ref byte[] ar, int startposition, int offset)
UInt32 sum_dw = 0;
i = (ushort)(count >> 1);
sum_dw = 0;
int j = 0;
while (i > 0)
{
UInt16 restored = BitConverter.ToUInt16(val, j);
sum_dw += restored;
String s = sum_dw.ToString("X");
System.Diagnostics.Debug.WriteLine("Number: "+i+" -- "+"value:" + s);
j += 2;
i--;
}
var aa = count & 0x1;
if (Convert.ToBoolean(aa))
{
byte restored = val[j];
sum_dw += (byte)restored;
}
byte[] sum_wb = BitConverter.GetBytes(sum_dw);
UInt16 sum_w0 = (UInt16)((UInt16)sum_wb[0] + (UInt32)(sum_wb[1]<<8));
UInt16 sum_w1 = (UInt16)((UInt16)sum_wb[2] + (UInt32)(sum_wb[3] << 8));
sum_dw = (UInt32)sum_w0 + (UInt32 )sum_w1;
sum_wb = BitConverter.GetBytes(sum_dw);
sum_w0 = (UInt16)((UInt16)sum_wb[0] + (UInt32)(sum_wb[1] << 8));
sum_w1 = (UInt16)((UInt16)sum_wb[2] + (UInt32)(sum_wb[3] << 8));
sum_w0 += sum_w1;
var reverse = ~(sum_w0);
UInt16 ans = (UInt16)(~(sum_w0));
System.Diagnostics.Debug.WriteLine("Asnwer: "+reverse);
return (UInt16)reverse;
}
Hope it helps

Related

Feistel Cipher in c#

I'm trying to implement a Feistel Cipher, I have the following code:
public static byte[] Encode(byte[] bytes) {
byte[] s = (byte[])bytes.Clone();
int half = s.Length / 2;
if (s.Length % 2 != 0)
throw new Exception("Unbalanced code");
byte[] left = new byte[half];
byte[] right = new byte[half];
Array.Copy(s, left, half);
Array.Copy(s, half, right, 0, half);
for (var k = 0; k < ROUNDS; k++) {
left = XOR(left,f(right));
var temp = left; left = right; right = temp;
}
byte[] toReturn = new byte[s.Length];
Array.Copy(left, 0, toReturn, half, half);
Array.Copy(right, 0, toReturn, 0, half);
return toReturn;
}
In this sample, ROUNDS is 21 and f is a function that rearranges the bytes in an array of bytes.
Unfortunately, while bytes should be equal to Encode(Encode(bytes)), it's not. And I have no idea what I'm doing wrong.
Any advice?
Edit: The code for f()
public static byte[] f(byte[] s) {
byte[] toReturn = (byte[])s.Clone();
byte temp = s[0];
for (var k = 1; k < s.Length; k++) {
s[k-1] = s[k];
s[k - 1] = (byte)(s[k - 1] ^ 45);
}
s[s.Length - 1] = temp;
s[s.Length - 1] = (byte)(s[s.Length - 1] ^ 45);
return toReturn;
}
CodesInChaos is correct, the problem was the variable being mutated.

Shifting a BitArray

I'm currently trying to shift a BitArray while keeping its length. Since there's no built-in method I'm struggling to build one but can't make it work, unfortunatly.
My initial BitArray code sets a length of 421 for the BitArray.
var b = new BitArray(length: 421);
Than, I'm assigning some values for testing. For instance:
b.Set(0, true);
b.Set(1, true);
However, I can't figure out how to shift the bit array.
Attempts:
- I thought that I could convert it into long and than make the bit manipulation. However, long does not match my exact BitArray length, which results in errors later on when I apply bitwise operations on two BitArrays (my full requirements is (array1 |= array2 >> 20).
- I tried to convert the BitArray into byte[], do the manipulation and return it (see Bit shifting N bits):
public static byte[] ToBytesArray(this BitArray array, int startIndex, int count)
{
// Get the size of bytes needed to store all bytes
int bytesize = count / ByteLength;
// Any bit left over another byte is necessary
if (count % ByteLength > 0)
{
bytesize++;
}
// For the result
byte[] bytes = new byte[bytesize];
// Must init to good value, all zero bit byte has value zero
// Lowest significant bit has a place value of 1, each position to
// to the left doubles the value
byte value = 0;
byte significance = 1;
int bytepos = 0;
int bitpos = startIndex;
while (bitpos - startIndex < count)
{
// If the bit is set add its value to the byte
if (array[bitpos])
value += significance;
bitpos++;
if (bitpos % ByteLength == 0)
{
// A full byte has been processed, store it
// increase output buffer index and reset work values
bytes[bytepos] = value;
bytepos++;
value = 0;
significance = 1;
}
else
{
// Another bit processed, next has doubled value
significance *= 2;
}
}
return bytes;
}
public static BitArray ShiftLeft(this BitArray array, int bitcount)
{
byte[] value = array.ToBytesArray();
byte[] temp = new byte[value.Length];
if (bitcount >= 8)
{
Array.Copy(value, bitcount / 8, temp, 0, temp.Length - (bitcount / 8));
}
else
{
Array.Copy(value, temp, temp.Length);
}
if (bitcount % 8 != 0)
{
for (int i = 0; i < temp.Length; i++)
{
temp[i] <<= bitcount % 8;
if (i < temp.Length - 1)
{
temp[i] |= (byte)(temp[i + 1] >> 8 - bitcount % 8);
}
}
}
return new BitArray(temp);
}
However, byte's length is 8, which can't fit well with my length too. The result is 416 or 424 (another byte) instead of 421.
Finally, I tried the "primitive" way:
for (int i = 0; i < bitcount; i++)
{
var lastValue = array[0];
for (var j = 0; j < array.Length - 1; j++)
{
array[j] = array[j + 1];
}
array[array.Length - 1] = lastValue;
}
I also check up SO (e.g. BitArray - Shift bits) but nothing worked for me.
Any help will be very appreciated!
Still not 100% sure what's the issue. Here's a naive implementation:
void Main()
{
// Creates and initializes a BitArrays of size 7 (you have 421).
bool[] myBools = new bool[7] { true,false,false,true,true,false,true };
BitArray myBA1 = new BitArray(myBools );
PrintBitArray(myBA1); // 1001101
PrintBitArray(ShiftRight(myBA1)); // 0100110
PrintBitArray(ShiftLeft (myBA1)); // 0011010
}
BitArray ShiftRight(BitArray aSource) {
bool[] new_arr = new bool[( aSource.Count)];
for (int i = 0; i < aSource.Count -1; i++)
new_arr[i+1] = aSource[i];
return new BitArray(new_arr);
}
BitArray ShiftLeft(BitArray aSource) {
bool[] new_arr = new bool[( aSource.Count)];
for (int i = 0; i < aSource.Count -1; i++)
new_arr[i] = aSource[i+1];
return new BitArray(new_arr);
}
string PrintBitArray(BitArray aSource) {
StringBuilder sb = new StringBuilder();
foreach (var bit in aSource)
{
sb.Append( (bool)bit ? 1 : 0 );
}
return sb.ToString();
}
Note how bits are copied in the loops, and that the third PrintBitArray is done on the original input, not on the outcome of the second.
public static bool[] Left_shiftBitArray(bool[] Array, int count)
{
Array = BitArray_LRotat(Array, count);
for (int i=Array.GetLength(0)-1; i>=(Array.GetLength(0)-count); i--)
{
Array[i] = false;
}
return Array;
}
public static bool[] BitArray_LRotat(bool[] input, int x)
{
//bool [] temp= new bool[input.Length];
bool[] final = new bool[input.Length];
for (int i = input.Length; i > x; i--)
{
final[i - x - 1] = input[i - 1];
}
for (int i = x; i > 0; i--)
{
final[(input.Length) - i] = input[x - i];
}
return final;
}

include two CRC16 bytes in a program ...?

i want to send some bytes via RS232 to a DSPIC33F that controls a robot motors, the DSPIC must receive 9 bytes orderly the last 2 bytes are for CRC16, am working in C#, so how can i calculate the CRC bytes meant to be sent.
the program that calculates the CRC16, i have found it in the internet :
using System;
using System.Collections.Generic;
using System.Text;
namespace SerialPortTerminal
{
public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }
public class Crc16Ccitt
{
const ushort poly = 4129;
ushort[] table = new ushort[256];
ushort initialValue = 0;
public ushort ComputeChecksum(byte[] bytes)
{
ushort crc = this.initialValue;
for (int i = 0; i < bytes.Length; i++)
{
crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
}
return crc;
}
public byte[] ComputeChecksumBytes(byte[] bytes)
{
ushort crc = ComputeChecksum(bytes);
return new byte[] { (byte)(crc >> 8), (byte)(crc & 0x00ff) };
}
public Crc16Ccitt(InitialCrcValue initialValue)
{
this.initialValue = (ushort)initialValue;
ushort temp, a;
for (int i = 0; i < table.Length; i++)
{
temp = 0;
a = (ushort)(i << 8);
for (int j = 0; j < 8; j++)
{
if (((temp ^ a) & 0x8000) != 0)
{
temp = (ushort)((temp << 1) ^ poly);
}
else
{
temp <<= 1;
}
a <<= 1;
}
table[i] = temp;
}
}
}
}
With the class you provided you would create the buffer of data that you want:
byte[] data = new byte[7];
data[0] = 1; // This example is just random numbers
data[1] = 12;
data[2] = 17;
data[3] = 9;
data[4] = 106;
data[5] = 12;
data[6] = 0;
Then calculate the checksum bytes:
Crc16Ccitt calculator = new Crc16Ccitt();
byte[] checksum = calculator.ComputeChecksumBytes(data);
Then either write the two parts of the data
port.Write(data);
port.Write(checksum);
Or build a packet to be written from the two parts:
byte[] finalData = new byte[9];
Buffer.BlockCopy(data, 0, finalData, 0, 7);
Buffer.BlockCopy(data, 7, checksum, 0, 2);
port.Write(finalData);
The class you've posted could be rewritten slightly to make it a bit more efficient and easier/cleaner to use but it should suffice as long as it calculates the CRC 16 in the same way as the device you're communicating with. If this doesn't work then you need to consult the documentation for the device, or ask the manufacturer for the details you need.

Float to 16bit, Stereo. Improve?

So i am converting Float 32bit, to 16Bit in Stereo. And as i don´t fully understand it myself, it´s pretty much copy paste sadly.
But i wonder if it can be improved, in either quality or speed?
Not that any of them are terrible or anything.
void SendWaloop(object sender, NAudio.Wave.WaveInEventArgs e)
{
byte[] newArray16Bit = new byte[e.BytesRecorded / 2];
short two;
float value;
for (int i = 0, j = 0; i < e.BytesRecorded; i += 4, j += 2)
{
value = (BitConverter.ToSingle(e.Buffer, i));
two = (short)(value * short.MaxValue);
newArray16Bit[j] = (byte)(two & 0xFF);
newArray16Bit[j + 1] = (byte)((two >> 8) & 0xFF);
}
if (connect == true && MuteMic.Checked == false)
{
udpSend.Send(newArray16Bit, newArray16Bit.Length, otherPartyIP.Address.ToString(), 1500);
}
}
So well, it´s converting the buffer from 32bit to 16bit, and send´s it with UDP, nothing weird.
Though for me this looks very complex, but from what i understand, it´s just removing every 4 byte or something like that.
EDIT:
unsafe
{
byte[] newArray16Bit = new byte[e.BytesRecorded / 2];
fixed (byte* sourcePtr = e.Buffer)
fixed (byte* targetPtr = newArray16Bit)
{
float* sourceTyped = (float*)sourcePtr;
short* targetTyped = (short*)targetPtr;
int count = e.BytesRecorded / 4;
for (int i = 0; i < count; i++)
{
targetTyped[i] = (short)(sourceTyped[i] * short.MaxValue);
}
}
if (connect == true && MuteMic.Checked == false)
{
udpSend.Send(newArray16Bit, newArray16Bit.Length, otherPartyIP.Address.ToString(), 1500);
}
}
}
It would need testing, but I would probably try with some unsafe:
fixed(byte* sourcePtr = e.Buffer)
fixed(byte* targetPtr = newArray16Bit)
{
float* sourceTyped = (float*)sourcePtr;
short* targetTyped = (short*)targetPtr;
int count = e.BytesRecorded / 4;
for(int i = 0 ; i < count ; i++)
{
targetTyped[i] = (short)(sourceTyped[i] * short.MaxValue);
}
}
To show that working identically:
using System;
static class Program
{
static void Main()
{
byte[] raw1 = new byte[64 * 1024];
new Random(12345).NextBytes(raw1); // 64k of random data
var raw2 = (byte[])raw1.Clone(); // just to rule out corruption
var result1 = OriginalImplFromTopPost(raw1, raw1.Length - 20);
var result2 = MyImpl(raw2, raw2.Length - 20);
bool areSame = Convert.ToBase64String(result1) == Convert.ToBase64String(result2);
Console.WriteLine(areSame); // True
}
public static unsafe byte[] MyImpl(byte[] source, int byteCount)
{
byte[] newArray16Bit = new byte[byteCount / 2];
fixed (byte* sourcePtr = source)
fixed (byte* targetPtr = newArray16Bit)
{
float* sourceTyped = (float*)sourcePtr;
short* targetTyped = (short*)targetPtr;
int count = byteCount / 4;
for (int i = 0; i < count; i++)
{
targetTyped[i] = (short)(sourceTyped[i] * short.MaxValue);
}
}
return newArray16Bit;
}
public static byte[] OriginalImplFromTopPost(byte[] source, int byteCount)
{
byte[] newArray16Bit = new byte[byteCount / 2];
short two;
float value;
for (int i = 0, j = 0; i < byteCount; i += 4, j += 2)
{
value = (BitConverter.ToSingle(source, i));
two = (short)(value * short.MaxValue);
newArray16Bit[j] = (byte)(two & 0xFF);
newArray16Bit[j + 1] = (byte)((two >> 8) & 0xFF);
}
return newArray16Bit;
}
}

Reading bit-aligned data

I have been reading the SWF format available on Adobe's site and it mentions that in order to save space, variable bits are used to store integers or floats (page 17 in the pdf)
I have always worked with byte-aligned data so have not given much thought to files that are bit-aligned, or have variable alignment where the information is stored in each byte.
So for example, you may have a struct containing four 13-bit integers stored sequentially ( rather than storing them as four 16-bit integers).
The first 13bits is the first integer, the next 13 bits is the second integer, and so on. It pads the last byte appropriate to make the struct byte-aligned with the rest of the file, so 52-bits would be padded to 56-bits, requiring 7 bytes to store those four integers as opposed to 8 bytes.
How do I approach this kind of problem?
How can I work with a stream of bytes at the bit-level?
Is there something I can use to help make it easier to work with this data?
I imagine the solution boils down to using bit-operations on byte arrays.
An example solution for parsing the four 13-bit integers would be nice as well to demonstrate the use of your suggested method.
There are two ways of dealing with this that I know of. The first is to manually do it - using bit-wise operators, division, modulus etc. on byte arrays [or integer/ulong etc if you were bored]. IsBitSet Example
The other way is a BitArray - which handles most of this for you :)
It would be nice to add an example of how exactly BitArray handles getting bits 13..25 as an int, as that would be the primary operation. At a first glance I see only a loop.
Fine... I wrote a quick & dirty test proof of concept:
var rnd = new Random();
//var data = Enumerable.Range(0, 10).ToArray();
var data = Enumerable.Range(0, 10).Select(x => rnd.Next(1 << 13)).ToArray();
foreach (var n in data) Console.WriteLine(n);
Console.WriteLine(new string('-', 13));
var bits = new BitArray(data.Length * 13);
for (int i = 0; i < data.Length; i++)
{
var intBits = new BitArray(new[] { data[i] });
for (int b = 12; b > -1; b--)
{
bits[i * 13 + b] = intBits[b];
Console.Write(intBits[b] ? 1 : 0);
}
Console.WriteLine();
}
Console.WriteLine(new string('-', 13));
for (int i = 0; i < bits.Length / 13; i++)
{
int number = 0;
for (int b = 12; b > -1; b--)
if (bits[i * 13 + b])
number += 1 << b;
Console.WriteLine(number);
}
Console.ReadLine();
Which outputs:
910
3934
7326
7990
7712
1178
6380
3460
5113
7489
-------------
0001110001110
0111101011110
1110010011110
1111100110110
1111000100000
0010010011010
1100011101100
0110110000100
1001111111001
1110101000001
-------------
910
3934
7326
7990
7712
1178
6380
3460
5113
7489
The bit array doesn't do much other than simplify accessing - it's still quite manual. I expect you'd write your own classes to simply this and make it neat and reusable - for example here's another quick concept:
//Improved to take sign into account.
//Sign is in addition to bits allocated for storage in this version.
//Stored as {sign}{bits}
//E.g. -5, stored in 3 bits signed is:
// 1 101
//E.g. 5, stored in 3 bits [with sign turned on]
// 0 101
//E.g. 5, stored in 3 bits no sign
// 101
//This may differ from your exiting format - e.g. you may use two's compliments.
static void Main(string[] args)
{
int bitsPerInt = 13;
//Create your data
var rnd = new Random();
//var data = Enumerable.Range(-5, 10).ToArray();
var data = Enumerable.Range(0, 10).Select(x => rnd.Next(-(1 << bitsPerInt), 1 << bitsPerInt)).ToArray();
var bits = new BitSerlializer();
//Add length header
bits.AddInt(data.Length, 8, false);
foreach (var n in data)
{
bits.AddInt(n, bitsPerInt);
Console.WriteLine(n);
}
//Serialize to bytes for network transfer etc.
var bytes = bits.ToBytes();
Console.WriteLine(new string('-', 10));
foreach (var b in bytes) Console.WriteLine(Convert.ToString(b, 2).PadLeft(8, '0'));
Console.WriteLine(new string('-', 10));
//Deserialize
bits = new BitSerlializer(bytes);
//Get Length Header
var count = bits.ReadInt(8, false);
for (int i = 0; i < count; i++)
Console.WriteLine(bits.ReadInt(bitsPerInt));
Console.ReadLine();
}
public class BitSerlializer
{
List<byte> bytes;
int Position { get; set; }
public BitSerlializer(byte[] initialData = null)
{
if (initialData == null)
bytes = new List<byte>();
else
bytes = new List<byte>(initialData);
}
public byte[] ToBytes() { return bytes.ToArray(); }
public void Addbit(bool val)
{
if (Position % 8 == 0) bytes.Add(0);
if (val) bytes[Position / 8] += (byte)(128 >> (Position % 8));
Position++;
}
public void AddInt(int i, int length, bool isSigned = true)
{
if (isSigned) Addbit(i < 0);
if (i < 0) i = -i;
for (int pos = --length; pos >= 0; pos--)
{
var val = (i & (1 << pos)) != 0;
Addbit(val);
}
}
public bool ReadBit()
{
var val = (bytes[Position / 8] & (128 >> (Position % 8))) != 0;
++Position;
return val;
}
public int ReadInt(int length, bool isSigned = true)
{
var val = 0;
var sign = isSigned && ReadBit() ? -1 : 1;
for (int pos = --length; pos >= 0; pos--)
if (ReadBit())
val += 1 << pos;
return val * sign;
}
}
On the other hand, byte-array-based approach could go like this:
int extend(uint raw, int bits)
{
int sh = 32 - bits;
int x = (int)raw << sh; // puts your sign bit in the highest bit.
return x >> sh; // since x is signed this is an arithmatic signed shift
}
int read(byte[] data, int pos, int bits, bool signed)
{
int fbi = pos / 8; // first byte index
int lbi = (pos + bits - 1) / 8; // last byte index
int cnt = lbi - fbi + 1; // bytes spanned
if (cnt > 3 || lbi >= data.Length) { throw new ArgumentException(); }
uint raw = (uint)(
(data[fbi] << (24 + pos % 8)) +
(cnt < 2 ? 0 : data[fbi + 1] << (16 + pos % 8)) +
(cnt < 3 ? 0 : data[fbi + 2] << (8 + pos % 8))
) >> (32 - bits);
return signed ? extend(raw, bits) : (int)raw;
}
Test for this:
byte[] test = { 0x55, 0xAA, 0x10 };
string s = "";
s += read(test, 0, 8, false) + "\r\n";
s += read(test, 0, 8, true) + "\r\n";
s += read(test, 8, 8, false) + "\r\n";
s += read(test, 8, 8, true) + "\r\n";
s += read(test, 4, 8, false) + "\r\n";
s += read(test, 7, 9, true) + "\r\n";
s += read(test, 7, 10, true) + "\r\n";
s += read(test, 7, 11, true) + "\r\n";
s += read(test, 7, 12, true) + "\r\n";
s += read(test, 7, 13, true) + "\r\n";
s += read(test, 7, 14, true) + "\r\n";
s += read(test, 7, 15, true) + "\r\n";
s += read(test, 7, 16, true) + "\r\n";
s += read(test, 7, 17, true) + "\r\n";
s += read(test, 18, 2, true) + "\r\n";
s += read(test, 18, 3, true) + "\r\n";
s += read(test, 23, 1, true) + "\r\n";
s += read(test, 23, 2, true) + "\r\n";
The test builds the string like the following:
85
85
170
-86
90
-86
-172
-344
-688
-1375
-2750
-5500
-11000
-22000
1
2
0
then throws an exception on the last line.

Categories