Вот вырезке из их документации:
Контрольная сумма CRC16 использует CCITT2Вопрос, что так тяжело описать что и зачем используете??? Какой полином??? В общем спасибо за сутки разбора...
-полином (х16 + х12 + х5
+ 1) и расчитывается по
полям Номер, Код, Параметры, CS и ETX без дублирующих и заключительного DLE. В ответном пакете
CRC16 подсчитывается аналогично.
ЭККР записывает полученный Номер и Код в ответное сообщение. Если ЭККР получает
сообщение, в котором совпадают значения полей Номер и Код со значениями предыдущего
сообщения, то он не выполняет команду, а повторяет передачу предыдущего сообщения.
Пример вычисления CRC16 на Си:
void CalcCRC16(BYTE *Buf, WORD Size, WORD *CRC16)
{char V;
while(Size--) {
V = *Buf++;
INT_HI(*CRC16) ^= V;
V = (INT_HI(*CRC16) << 4) ^ INT_HI(*CRC16); INT_HI(*CRC16) = (V >> 4) ^ (V << 3) ^ INT_LO(*CRC16); INT_LO(*CRC16) = (V >> 5) ^ V;
}
}
Пример вычисления CRC16 на Паскале:
function CalcCRC16(DataByte: Byte; CRC16: word): word;
var
a:word;
begin
CRC16 := CRC16 xor DataByte;
a:=(CRC16 xor (CRC16 shl 4)) and $00FF;
Result:=(CRC16 shr 8) xor (a shl 8) xor (a shl 3) xor (a shr 4);
end;
Решение было сделано так:
0. спасибо утилите serial port monitor, за то что удалось посмотреть, как обмениваться между собой аппарат и утилита ИКС
1.найден был сайт с online калькулятором расчета CRC.
2. Благодаря калькулятору удалось понять какой метод шифрования необходимо использовать - CRC-CCITT (Kermit), ИКС что так сложно описать???
3. Найдено решение спасибо гугл и stackoverflow
оставлю код для необходимости:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { byte ETX = 0x03; byte DLE = 0x10; byte STX = 0x02; byte ASK = 0x06; //Crc16Ccitt crc16 = new Crc16Ccitt(x); // 10 02 46 00 ba 10 03 a8 a8 ..F.є..ЁЁ // 10 02 56 00 aa 10 03 98 fe ..V.Є..ю // 10 02 60 00 a0 10 03 80 04..`. ..Ђ. // 10 02 6b 32 00 00 00 00 63 10 03 3a e8 ..k2....c..:и // 10 02 6a 00 96 10 03 5c 3a ..j.–..\: // 10 02 73 32 00 00 09 00 52 10 03 e7 c8 ..s2....R..зИ // 10 02 5f 32 00 00 09 00 66 10 03 b7 94 .._2....f..·” // 10 02 74 00 8c 10 03 5e 3f ..t.Њ..^? // 10 02 75 32 00 00 00 00 59 10 03 9d c8 ..u2....Y..ќИ // 10 02 76 32 00 00 01 00 57 10 03 e6 c4 ..v2....W..жД //Array<byte[]> myList = new Array<byte[]>(); //myList.Add({ 0x10, 0x02, 0x46, 0x00, 0xba, 0x10, 0x03, 0xa8, 0xa8 }); //byte[] temp = { 0x10, 0x02, 0x56, 0x00, 0xaa, 0x10, 0x03, 0x98, 0xfe }; ArrayList myList = new ArrayList(); byte[] arrayofbytes = { 0x10, 0x02, 0x46, 0x00, 0xba, 0x10, 0x03, 0xa8, 0xa8 }; myList.Add(arrayofbytes); arrayofbytes = new byte[] { 0x10, 0x02, 0x56, 0x00, 0xaa, 0x10, 0x03, 0x98, 0xfe }; myList.Add(arrayofbytes); arrayofbytes = new byte[] { 0x10, 0x02, 0x76, 0x32, 0x00, 0x00, 0x01, 0x00, 0x57, 0x10, 0x03, 0xe6, 0xc4 }; myList.Add(arrayofbytes); byte[] bytebegin = { DLE, STX}; byte[] byteend = {DLE, ETX}; Crc16 testCRC16 = new Crc16(Crc16Mode.CcittKermit); //ushort max = ushort.MaxValue; //for (ushort x = 0; x <= max - 1; x++) //{ //Console.WriteLine(x); foreach (byte[] tempa in myList) { //Console.WriteLine(PrintByteArray(tempa)); byte[] tempb = returnWithOutDublicateETX(tempa); var searchBegin = PatternAt(tempb, bytebegin); if (searchBegin == null) continue; var searchEnd = PatternAt(tempb, byteend); if (searchEnd == null) continue; var newArr = tempb.Skip((int)searchBegin+2).Take((int)searchEnd-2).ToArray(); byte[] a = new byte[newArr.Length+1]; newArr.CopyTo(a, 0); a[newArr.Length] = ETX; //Console.WriteLine(PrintByteArray(a)); var control = tempb.Skip((int)searchEnd+2).Take(2).ToArray(); //Console.WriteLine(PrintByteArray(control)); //byte[] crc = BitConverter.GetBytes(compute_fcs(a, x)); byte[] crc = testCRC16.ComputeChecksumBytes(a); if ((crc[0] == control[0]) && (crc[1] == control[1])) { Console.WriteLine(PrintByteArray(tempa)); Console.WriteLine(PrintByteArray(a)); Console.WriteLine(PrintByteArray(control)); // Console.WriteLine(x); Console.WriteLine(PrintByteArray(crc)); Console.ReadKey(); //break; } } //break; //} Console.WriteLine("The End!!!!"); Console.ReadKey(); } static byte[] returnWithOutDublicateETX(byte[] source) { return returnWithOutDublicate(source, new byte[] { 0x10, 0x10 }); } static byte[] returnWithOutDublicate(byte[] source, byte[] pattern) { List<byte> tReturn =new List<byte>(); int sLenght = source.Length; for (int i = 0; i < sLenght; i++) { if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern)) { tReturn.Add(source[i]); i++; } else { tReturn.Add(source[i]); } } return (byte[])tReturn.ToArray(); } static int? PatternAt(byte[] source, byte[] pattern) { for (int i = 0; i < source.Length; i++) { if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern)) { return i; } } return null; } static string PrintByteArray(byte[] bytes) { var sb = new StringBuilder("new byte[] { "); foreach (var b in bytes) { sb.AppendFormat("{0:x2}", b); sb.Append(" "); } sb.Append("}"); return sb.ToString(); } /// 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; } } } //// } }
No comments:
Post a Comment