Xor-el / HashLib4Pascal

Hashing for Modern Object Pascal
MIT License
220 stars 80 forks source link

Help needed trying to figure hash method #26

Closed ertankucukoglu closed 1 year ago

ertankucukoglu commented 1 year ago

Hello,

First of all thank you again for making this library MIT license and thank you to all who supported that.

I am provided a documentation for TLV communication with a device. There is no specific standard clearly indicated in the document. It says "CRC calculation". I assumed that is CRC16 since size in communication is 2 bytes only.

There is an example application provided. No SDK or code examples from the seller of the device, I am alone to solve this one.

Below is the data sent to the device by sample application. 02 at the beginning and 03 at the end should not be included in CRC calculation and F39A is the calculated CRC. 02 0017544553543030303032363036FF8A7507DF820803000001 F39A 03

I have following code that tries to calculate all supported CRC16 values for 0017544553543030303032363036FF8A7507DF820803000001 value

var
  LCRC: IHash;
  Bytes: TBytes;
  CRC: TBytes;
  I: Integer;
begin
  Bytes := string(Edit1.Text).StrToBytes(); // my own helper function

  for I := 49 to 77 do // loop all CRC16 standards
  begin
    LCRC := THashFactory.TChecksum.TCRC.CreateCRC(TCRCStandard(I));
    CRC := (LCRC as ICRC).ComputeBytes(Bytes).GetBytes;
    Memo1.Lines.Add(CRC.ToHex() + ' ' + LCRC.Name);
    CRC := [];
    LCRC := nil;
  end;
end;

My problem is output always adds to previous result as below

540D TCRC-16/AUG-CCITT
540D8FFD TCRC-16/BUYPASS
540D8FFDAA9F TCRC-16/CCITT-FALSE
540D8FFDAA9FA7CB TCRC-16/CDMA2000
540D8FFDAA9FA7CBE13A TCRC-16/CMS
540D8FFDAA9FA7CBE13A696A TCRC-16/DDS-110
540D8FFDAA9FA7CBE13A696A712C TCRC-16/DECT-R
540D8FFDAA9FA7CBE13A696A712C712D TCRC-16/DECT-X
540D8FFDAA9FA7CBE13A696A712C712DB27E TCRC-16/DNP
540D8FFDAA9FA7CBE13A696A712C712DB27ED177 TCRC-16/EN13757
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560 TCRC-16/GENIBUS
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A1 TCRC-16/GSM
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8 TCRC-16/LJ1200
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E TCRC-16/MAXIM
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E6254 TCRC-16/MCRF4XX
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3 TCRC-16/OPENSAFETY-A
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC38860 TCRC-16/OPENSAFETY-B
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA TCRC-16/PROFIBUS
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D TCRC-16/RIELLO
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF TCRC-16/T10-DIF
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8 TCRC-16/TELEDISK
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF TCRC-16/TMS37157
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048 TCRC-16/USB
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048C988 TCRC-A
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048C988E135 TKERMIT
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048C988E135AFB7 TMODBUS
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048C988E135AFB79DAB TX-25
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048C988E135AFB79DAB2C5E TXMODEM
540D8FFDAA9FA7CBE13A696A712C712DB27ED1775560D3A192F8B33E62545BC3886051DA038D67EF5BA8ABBF5048C988E135AFB79DAB2C5E2CB1 TCRC-16/NRSC-5

I just cannot be sure that the calculation actually works fresh for each loop.

How can I clear buffer/data in the loop?

Thanks & Regards, Ertan

Xor-el commented 1 year ago

Hi @ertankucukoglu I can't seem to reproduce the issue you are having with my simple demo attached below (at least while running on Delphi).

program CRCTest;

uses
  HlpHashFactory,
  HlpIHash,
  HlpCRC,
  HlpICRC,
  HlpConverters,
  System.SysUtils;

var
  LCRC: IHash;
  Bytes: TBytes;
  CRC: TBytes;
  I: Integer;

begin

  try
    var
    str := '0017544553543030303032363036FF8A7507DF820803000001';

    Bytes := TConverters.ConvertHexStringToBytes(str);

    for I := 49 to 77 do // loop all CRC16 standards
    begin
      LCRC := THashFactory.TChecksum.TCRC.CreateCRC(TCRCStandard(I));
      CRC := (LCRC as ICRC).ComputeBytes(Bytes).GetBytes;
      Writeln(TConverters.ConvertBytesToHexString(CRC, false) + ' ' +
        LCRC.Name);
      CRC := [];
      LCRC := nil;

    end;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

Note, I only swapped out your helper functions for mine as I do not have access to yours.

output from above is attached below

540D TCRC-16/AUG-CCITT
8FFD TCRC-16/BUYPASS
AA9F TCRC-16/CCITT-FALSE
A7CB TCRC-16/CDMA2000
E13A TCRC-16/CMS
696A TCRC-16/DDS-110
712C TCRC-16/DECT-R
712D TCRC-16/DECT-X
B27E TCRC-16/DNP
D177 TCRC-16/EN13757
5560 TCRC-16/GENIBUS
D3A1 TCRC-16/GSM
92F8 TCRC-16/LJ1200
B33E TCRC-16/MAXIM
6254 TCRC-16/MCRF4XX
5BC3 TCRC-16/OPENSAFETY-A
8860 TCRC-16/OPENSAFETY-B
51DA TCRC-16/PROFIBUS
038D TCRC-16/RIELLO
67EF TCRC-16/T10-DIF
5BA8 TCRC-16/TELEDISK
ABBF TCRC-16/TMS37157
5048 TCRC-16/USB
C988 TCRC-A
E135 TKERMIT
AFB7 TMODBUS
9DAB TX-25
2C5E TXMODEM
2CB1 TCRC-16/NRSC-5

Are you certain your ToHex extension does not cache the result of it's previous computation to a global variable?

ertankucukoglu commented 1 year ago

I confirm that the issue does not exist on console application. You are correct that it is my helper function TBytes.ToHex() causing problems. Sorry about the noise.

BTW, I still cannot get any F39A as a result. I doubt it but, is there any CRC 16 standard which HashLib4Pascal does not support?

Xor-el commented 1 year ago

So HashLib4Pascal supports all standard CRC's except CRC 82. That been said, if the data you are hashing is the correct one expected to give you that checksum then there is one other suspicion, that the specified CRC is a custom one. For you to test out that theory, you need some details about the CRC you are trying to compute such as

  1. Polynomial
  2. Initial Value
  3. ReflectIn
  4. ReflectOut
  5. OutputXor

Do you by chance have the polynomial of the crc you wish to compute?

ertankucukoglu commented 1 year ago

Unfortunately, not. Only information I have is I need to calculate CRC of 2 bytes. I have no expectations at all but I am expecting an answer for tomorrow.

Given I have a custom CRC at hand and all these details about it, can I use HashLib4Pascal as it is to calculate that custom CRC, or there is still need for implementation?

Thank you.

Xor-el commented 1 year ago

You can calculate a custom CRC using HashLib4Pascal but you need those 5 details I requested above as those are the building blocks for any CRC implementation.

ertankucukoglu commented 1 year ago

Here are the details I found

  1. Polynomial: 0x8005
  2. Initial Value: 0x0000
  3. ReflectIn: True
  4. ReflectOut: True
  5. OutputXor: 0x0000

Algorithm is called as CRC-16/ARC by this web site. https://crccalc.com

Now, I am just not sure how I should use these values for custom CRC calculation.

BTW, input hex data is 544553543030303032363036FF8A7507DF820803000001

Thanks & Regards, Ertan

Xor-el commented 1 year ago

first of all, the CRC you are looking for TCRCStandard.ARC already exists so no need to do any custom calculations. your original code had a couple of issues though.

  1. you didn't include CRC ARC in your loop, you were meant to start the loop from 48.
  2. your original input data was wrong.
ertankucukoglu commented 1 year ago

You are right on your listed issues.

  1. I didn't know that CRC ARC belongs to CRC16 group and thought the naming convention starts with CRC16 for all in the CTRL+SPACE list within Delphi IDE. image Just by looking at the list closely and one can see sequential numbers skip 48. I can see it now.

  2. Seller of the device I am working provided absolutely no details as to CRC. I just know it is 2 bytes and its position in the data packet. I was doing trial and error until I actually find input data and the standard.

As always, thank you for your support.

Xor-el commented 1 year ago

Glad I was able to help.