I'm currently working on a hard way that requires the CRC_CCITT Kermit 16 protocol with the formula (X16 + X12 + X5 + 1). However some of the code I've found online both on this site or the web in general I don't seem to get my desired result. I saw this website (http://www.lammertbies.nl/comm/info/crc-calculation.html) that actually provides me with the exact match I want but it was written in C++. So can anyone help me with this?
I look forward to hearing from you.
Kind regards
Michael
if you need CRC CCITT 16 Kermit you'll need the following code (from my site):
var crc16Kermit = new Crc16( Crc16Mode.CcittKermit );
var checksum = crc16Kermit.ComputeChecksumBytes( 0x01, 0x23, 0x45 );
// checksum = 0x2e, 0x46
here's the source for the above code
using System;
public enum Crc16Mode : ushort { Standard = 0xA001, CcittKermit = 0x8408 }
public class Crc16 {
static ushort[] table = new ushort[256];
public ushort ComputeChecksum( params byte[] bytes ) {
ushort crc = 0;
for(int i = 0; i < bytes.Length; ++i) {
byte index = (byte)(crc ^ bytes[i]);
crc = (ushort)((crc >> 8) ^ table[index]);
}
return crc;
}
public byte[] ComputeChecksumBytes( params byte[] bytes ) {
ushort crc = ComputeChecksum( bytes );
return BitConverter.GetBytes( crc );
}
public Crc16( Crc16Mode mode ) {
ushort polynomial = (ushort)mode;
ushort value;
ushort temp;
for(ushort i = 0; i < table.Length; ++i) {
value = 0;
temp = i;
for(byte j = 0; j < 8; ++j) {
if(((value ^ temp) & 0x0001) != 0) {
value = (ushort)((value >> 1) ^ polynomial);
}else {
value >>= 1;
}
temp >>= 1;
}
table[i] = value;
}
}
}
link for the above code: http://sanity-free.org/147/standard_crc16_and_crc16_kermit_implementation_in_csharp.html
Seems you want CRC16 CCITT. Try this:
using System;
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 BitConverter.GetBytes(crc);
}
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;
}
}
}
Source:
http://sanity-free.org/133/crc_16_ccitt_in_csharp.html
Related
I want to use the Diffie Hellman algorithm to securely exchange keys between a C++ server an a C# client which both are running on Windows. I tried using ECDiffieHellmanCng in C# to generate a public key as follows:
ECDiffieHellmanCng diffieHellman = new ECDiffieHellmanCng
{
KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash,
HashAlgorithm = CngAlgorithm.Sha256
};
byte[] publicKey = diffieHellman.PublicKey.ToByteArray(); // 140 bytes
Furthermore, I'm deriving the AES key using the following code:
var cngKey = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
var aesKey = diffieHellman.DeriveKeyMaterial(cngKey); // 32 bytes
This works well in a C# context, however I need it to interact with C++.
Is there any C++ library or code which is compatible with ECDiffieHellmanCng? I looked into Crypto++ but it wants me to generate a p, q, and g as well as the public key size being 128 bytes which looks like it's not compatible with my C# key exchange method.
Any other suggestions or code examples for performing the key exchange are welcome regardless.
Since I simply wanted an encrypted connection, going with OpenSSL was the way to go.
Maybe this will help you a bit?
#pragma warning(disable : 4996)
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include "openssl/dh.h"
#include "openssl/bn.h"
#include "openssl/pem.h";
using namespace std;
DH *dhp = NULL;
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++)
char_array_4[j] = 0;
for (j = 0; j < 4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
int main(int argc, char *argv[])
{
BIGNUM* priv_key = NULL;
BIGNUM* apub_key = NULL;
BIGNUM* p = NULL;
BIGNUM* g = NULL;
std::string userPubKey;
std::string prime;
std::string generator;
if (argc < 6) {
printf("%s", "Missing parameters: -p, -key -g");
return -1;
}
//Process parameters
int count;
for (count = 1; count < argc; count+=2)
{
std::string param = (string)argv[count];
if (strcmpi(param.c_str(), "-p") == 0) {
prime = (string)argv[count+1];
}
else if (strcmpi(param.c_str(), "-key") == 0) {
userPubKey = (string)argv[count + 1];
}
else if (strcmpi(param.c_str(), "-g") == 0) {
generator = (string)argv[count+1];
}
}
//Set public key of remote User
BN_hex2bn(&apub_key, userPubKey.c_str());
DH *dhp = DH_new();
if (dhp == NULL) {
return -1;
}
//Set Prime and Generator
BN_hex2bn(&p, prime.c_str());
BN_dec2bn(&g, generator.c_str());
DH_set0_pqg(dhp, p, NULL, g);
if (DH_generate_key(dhp) != 1) {
printf("%s", "Error generating keys.");
return -1;
}
//Print Public Key as Hex
const BIGNUM* exportPublic = DH_get0_pub_key(dhp);
printf("Public Key: %s\r\n", BN_bn2hex(exportPublic));
//Calculate secret
char buf[256] = { 0 };
unsigned char* abuf = NULL;
int alen = DH_size(dhp);
abuf = (unsigned char*)OPENSSL_malloc(alen);
int aout = DH_compute_key(abuf, apub_key, dhp);
printf("\r\nThe shared secret is:\r\n");
std::string encoded = base64_encode(abuf, aout);
printf("%s\r\n", encoded.c_str());
DH_free(dhp);
p = NULL;
g = NULL;
abuf = NULL;
}
I got this class to compute the CRC8 checksum of a byte[]:
public static class Crc8
{
static byte[] table = new byte[256];
// x8 + x7 + x6 + x4 + x2 + 1
const byte poly = 0xd5;
public static byte ComputeChecksum(params byte[] bytes)
{
byte crc = 0;
if (bytes != null && bytes.Length > 0)
{
foreach (byte b in bytes)
{
crc = table[crc ^ b];
}
}
return crc;
}
static Crc8()
{
for (int i = 0; i < 256; ++i)
{
int temp = i;
for (int j = 0; j < 8; ++j)
{
if ((temp & 0x80) != 0)
{
temp = (temp << 1) ^ poly;
}
else
{
temp <<= 1;
}
}
table[i] = (byte)temp;
}
}
}
And in the Main I got:
static void Main(string[] args)
{
string number = "123456789";
Console.WriteLine(Convert.ToByte(Crc8.ComputeChecksum(StringToByteArray(number))).ToString("x2"));
Console.ReadLine();
}
private static byte[] StringToByteArray(string str)
{
ASCIIEncoding enc = new ASCIIEncoding();
return enc.GetBytes(str);
}
This results in 0xBC
However, according to: http://www.scadacore.com/field-tools/programming-calculators/online-checksum-calculator/
this is incorrect, because the checksum for the CheckSum8 Xor is 0x31.
What did I wrong there?
On the linked site only some 16 and 32 bit CRCs are listed, the
CheckSum8Xor is not a CRC. The 0xBC comes from a 8-bit CRC
called "CRC-8/DVB-S2", see http://reveng.sourceforge.net/crc-catalogue/1-15.htm
Ah, ok, so I've overiterpreted this checksum computation.
Well, in that case, it's easy:
public static byte Checksum8XOR(byte[] data)
{
byte checksum = 0x00;
for (int i = 0; i < data.Length; i++)
{
checksum ^= data[i];
}
return checksum;
}
I am trying to generate a CRC-16 using C#. The hardware I am using for RS232 requires the input string to be HEX. The screenshot below shows the correct conversion, For a test, I need 8000 to be 0xC061, however the C# method that generates CRC-16 must be able to convert any given HEX string.
I have tried using Nito.KitchenSink.CRC
I have also tried the below which generates 8009 when 8000 is inputted -
public string CalcCRC16(string strInput)
{
ushort crc = 0x0000;
byte[] data = GetBytesFromHexString(strInput);
for (int i = 0; i < data.Length; i++)
{
crc ^= (ushort)(data[i] << 8);
for (int j = 0; j < 8; j++)
{
if ((crc & 0x8000) > 0)
crc = (ushort)((crc << 1) ^ 0x8005);
else
crc <<= 1;
}
}
return crc.ToString("X4");
}
public Byte[] GetBytesFromHexString(string strInput)
{
Byte[] bytArOutput = new Byte[] { };
if (!string.IsNullOrEmpty(strInput) && strInput.Length % 2 == 0)
{
SoapHexBinary hexBinary = null;
try
{
hexBinary = SoapHexBinary.Parse(strInput);
if (hexBinary != null)
{
bytArOutput = hexBinary.Value;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return bytArOutput;
}
Here we go; note that this is a specific flavor of CRC-16 - it is confusing to say just "CRC-16". This borrows some implementation specifics from http://www.sanity-free.com/ - note I have made it static rather than instance-based.
using System;
static class Program
{
static void Main()
{
string input = "8000";
var bytes = HexToBytes(input);
string hex = Crc16.ComputeChecksum(bytes).ToString("x2");
Console.WriteLine(hex); //c061
}
static byte[] HexToBytes(string input)
{
byte[] result = new byte[input.Length / 2];
for(int i = 0; i < result.Length; i++)
{
result[i] = Convert.ToByte(input.Substring(2 * i, 2), 16);
}
return result;
}
public static class Crc16
{
const ushort polynomial = 0xA001;
static readonly ushort[] table = new ushort[256];
public static ushort ComputeChecksum(byte[] bytes)
{
ushort crc = 0;
for (int i = 0; i < bytes.Length; ++i)
{
byte index = (byte)(crc ^ bytes[i]);
crc = (ushort)((crc >> 8) ^ table[index]);
}
return crc;
}
static Crc16()
{
ushort value;
ushort temp;
for (ushort i = 0; i < table.Length; ++i)
{
value = 0;
temp = i;
for (byte j = 0; j < 8; ++j)
{
if (((value ^ temp) & 0x0001) != 0)
{
value = (ushort)((value >> 1) ^ polynomial);
}
else
{
value >>= 1;
}
temp >>= 1;
}
table[i] = value;
}
}
}
}
In Addition, If you want CRC16-CCITT.
private ushort Crc16Ccitt(byte[] bytes)
{
const ushort poly = 4129;
ushort[] table = new ushort[256];
ushort initialValue = 0xffff;
ushort temp, a;
ushort crc = initialValue;
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;
}
for (int i = 0; i < bytes.Length; ++i)
{
crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
}
return crc;
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
i try use this code to make decrypt it but it's have problem i use CryperCounter to use make counter in first make PrepareAuthCryptography then use authCryptography key2 use >> 8 and Key1 use & 0xff see the code and you will understand it
public class AuthCryptography
{
class CryptCounter
{
public CryptCounter()
{
}
public CryptCounter(ushort with)
{
m_Counter = with;
}
UInt16 m_Counter = 0;
public byte Key2
{
get { return (byte)(m_Counter >> 8); }
}
public byte Key1
{
get { return (byte)(m_Counter & 0xFF); }
}
public void Increment()
{
m_Counter++;
}
}
private CryptCounter _decryptCounter;
private CryptCounter _encryptCounter;
private static byte[] _cryptKey1;
private static byte[] _cryptKey2;
public static void PrepareAuthCryptography()
{
if (_cryptKey1 != null)
{
if (_cryptKey1.Length != 0)
return;
}
_cryptKey1 = new byte[0x100];
_cryptKey2 = new byte[0x100];
byte i_key1 = 0x9D;
byte i_key2 = 0x62;
for (int i = 0; i < 0x100; i++)
{
_cryptKey1[i] = i_key1;
_cryptKey2[i] = i_key2;
i_key1 = (byte)((0x0F + (byte)(i_key1 * 0xFA)) * i_key1 + 0x13);
i_key2 = (byte)((0x79 - (byte)(i_key2 * 0x5C)) * i_key2 + 0x6D);
}
}
public AuthCryptography()
{
_encryptCounter = new CryptCounter();
_decryptCounter = new CryptCounter();
}
public void Encrypt(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)0xAB;
buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= (byte)(_cryptKey1[_encryptCounter.Key1] ^ _cryptKey2[_encryptCounter.Key2]);
_encryptCounter.Increment();
}
}
public void Decrypt(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)0xAB;
buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
buffer[i] ^= (byte)(_cryptKey2[_decryptCounter.Key2] ^ _cryptKey1[_decryptCounter.Key1]);
_decryptCounter.Increment();
}
}
public void Decrypt4(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] ^= (byte)(_cryptKey1[_encryptCounter.Key1] ^ _cryptKey2[_encryptCounter.Key2]);
buffer[i] = (byte)(buffer[i] << 4 | buffer[i] >> 4);
buffer[i] ^= (byte)0xAB;
_encryptCounter.Increment();
}
}
}
The decrypt should be the inverse of the encrypt, in this case (a pipeline of reversible operations), just reverse the operations. Like this (not tested):
public static void Decrypt(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
int temp = buffer[i] ^ _cryptKey2[_decryptCounter.Key2] ^ _cryptKey1[_decryptCounter.Key1];
temp = (temp >> 4) | (temp << 4);
temp ^= 0xAB;
buffer[i] = (byte)temp;
_decryptCounter.Increment();
}
}
That's equivalent to:
public static void Decrypt(byte[] buffer)
{
for (int i = 0; i < buffer.Length; i++)
{
int temp = buffer[i] ^ 0xBA ^ _cryptKey2[_decryptCounter.Key2] ^ _cryptKey1[_decryptCounter.Key1];
temp = (temp >> 4) | (temp << 4);
buffer[i] = (byte)temp;
_decryptCounter.Increment();
}
}
So, bitfields. Specifically, large bitfields. I understand how to manipulate individual values in a bitfield, but how would I go about doing this on a large set, such as say:
uint[] bitfield = new uint[4] { 0x0080000, 0x00FA3020, 0x00C8000, 0x0FF00D0 };
The specific problem I'm having is doing left and right shifts that carry through across the whole array. So for instance, if I did a >> 4 on the above array, I'd end up with:
uint[4] { 0x0008000, 0x000FA302, 0x000C800, 0x00FF00D };
Now, an (overly) simplistic algorithm here might look something like (this is me writting code on the fly):
int shift = 4;
for (int i = 0; i <= shift; i++) {
for (int j = bitfield.GetUpperBound(0); j > 0; j--) {
bitfield[j] = bitfield[j] >> 1;
bitfield[j] = bitfield[j] + ((bitfield[j-1] & 1) << (sizeof(uint)*8));
}
bitfield[0] = bitfield[0] >> 1;
}
Is there anything built in that might ease working with this sort of data?
What makes you think that BitArray uses bools internally? It uses Boolean values to represent the bits in terms of the API, but under the hood I believe it uses an int[].
I'm not sure if it's the best way to do it, but this could work (constraining shifts to be in the range 0-31.
public static void ShiftLeft(uint[] bitfield, int shift) {
if(shift < 0 || shift > 31) {
// handle error here
return;
}
int len = bitfield.Length;
int i = len - 1;
uint prev = 0;
while(i >= 0) {
uint tmp = bitfield[i];
bitfield[i] = bitfield[i] << shift;
if(i < len - 1) {
bitfield[i] |= (uint)(prev & (1 >> shift) - 1 ) >> (32 - shift);
}
prev = tmp;
i--;
}
}
public static void ShiftRight(uint[] bitfield, int shift) {
if(shift < 0 || shift > 31) {
// handle error here
return;
}
int len = bitfield.Length;
int i = 0;
uint prev = 0;
while(i < len) {
uint tmp = bitfield[i];
bitfield[i] = bitfield[i] >> shift;
if(i > 0) {
bitfield[i] |= (uint)(prev & (1 << shift) - 1 ) << (32 - shift);
}
prev = tmp;
i++;
}
}
PD: With this change, you should be able to handle shifts greater than 31 bits. Could be refactored to make it look a little less ugly, but in my tests, it works and it doesn't seem too bad performance-wise (unless, there's actually something built in to handle large bitsets, which could be the case).
public static void ShiftLeft(uint[] bitfield, int shift) {
if(shift < 0) {
// error
return;
}
int intsShift = shift >> 5;
if(intsShift > 0) {
if(intsShift > bitfield.Length) {
// error
return;
}
for(int j=0;j < bitfield.Length;j++) {
if(j > intsShift + 1) {
bitfield[j] = 0;
} else {
bitfield[j] = bitfield[j+intsShift];
}
}
BitSetUtils.ShiftLeft(bitfield,shift - intsShift * 32);
return;
}
int len = bitfield.Length;
int i = len - 1;
uint prev = 0;
while(i >= 0) {
uint tmp = bitfield[i];
bitfield[i] = bitfield[i] << shift;
if(i < len - 1) {
bitfield[i] |= (uint)(prev & (1 >> shift) - 1 ) >> (32 - shift);
}
prev = tmp;
i--;
}
}
public static void ShiftRight(uint[] bitfield, int shift) {
if(shift < 0) {
// error
return;
}
int intsShift = shift >> 5;
if(intsShift > 0) {
if(intsShift > bitfield.Length) {
// error
return;
}
for(int j=bitfield.Length-1;j >= 0;j--) {
if(j >= intsShift) {
bitfield[j] = bitfield[j-intsShift];
} else {
bitfield[j] = 0;
}
}
BitSetUtils.ShiftRight(bitfield,shift - intsShift * 32);
return;
}
int len = bitfield.Length;
int i = 0;
uint prev = 0;
while(i < len) {
uint tmp = bitfield[i];
bitfield[i] = bitfield[i] >> shift;
if(i > 0) {
bitfield[i] |= (uint)(prev & (1 << shift) - 1 ) << (32 - shift);
}
prev = tmp;
i++;
}
}
Using extension methods, you could do this:
public static class BitArrayExtensions
{
public static void DownShift(this BitArray bitArray, int places)
{
for (var i = 0; i < bitArray.Length; i++)
{
bitArray[i] = i + places < bitArray.Length && bitArray[i + places];
}
}
public static void UpShift(this BitArray bitArray, int places)
{
for (var i = bitArray.Length - 1; i >= 0; i--)
{
bitArray[i] = i - places >= 0 && bitArray[i - places];
}
}
}
Unfortunately, I couldn't come up with a way to overload the shift operators. (Mainly because BitArray is sealed.)
If you intend to manipulate ints or uints, you could create extension methods for inserting bits into / extracting bits from the BitArray. (BitArray has a constructor that takes an array of ints, but that only takes you that far.)
This doesn't cover specifically shifting, but could be useful for working with large sets. It's in C, but I think it could be easily adapted to C#
Is there a practical limit to the size of bit masks?