jkeen / tracking_number_data

Shared data for cross platform tracking number detection
MIT License
113 stars 38 forks source link

Deutsche Post DHL Tracking numbers not working #30

Open matwithers opened 4 years ago

matwithers commented 4 years ago

Hi

Love this gem, it's working really well for us tracking UPS in the UK. We've just started shipping in Germany using Deutsche Post DHL. All of the tracking numbers we have are 20 Digits long and seem to start with the digits 00340434

Does anyone have any idea about the format of these tracking numbers ? I'd like to try and help to add support but I can't find if there is any further information embedded.

jkeen commented 1 year ago

I started looking into this and found some documentation on it, but the checksum algorithm is a more complicated than the standard fare, and I'm having some trouble finding an implementation to add to tracking_number.

They say it's a CRC-4 checksum algorithm and digest-crc has every CRC-related algorithm but that particular one, it seems. Bit shifting algorithms are not my forte.

MarcoWel commented 1 year ago

For DHL Parcels (national/EU/international), you can check the regex format here: https://github.com/karrioapi/karrio-dashboard/issues/262#issuecomment-1561174857

It is most common for any commercial shipments with DHL. For checksum calculation of DHL tracking IDs, this is helpful (in German though): https://www.paketda.de/firmenkunden/paket-pruefziffern.html


Then there is Deutsche Post letter mail which works a bit differently. Those shipments cannot be tracked by the DHL API, only with a dedicated tracking for Deutsche Post: https://www.deutschepost.de/sendung/simpleQuery.html?locale=en_GB

For most registered international mailing with Deutsche Post, tracking numbers usually start with R and end with DE. There might be 3 trailing digits, which are usually omitted though.

Example 1: RC123456789DE
Example 2: RP123456789DE110
Regex:     R[A-Z]{1}[0-9]{9}DE([0-9]{3})?

Then for some Deutsche Post letters, there is only a 20-hex-digit "Franking ID" shown on the label looking like follows:

Example: A2 0100 001D 00 010A E9FF
Regex:   [A-F0-9]{20}

This ID including checksum calculation described in chapter 6.2 of the document you linked above: https://www.deutschepost.de/content/dam/dpag/images/D_d/DV-Freimachung/downloads/dp-dv-freimachung-mlfvm-1-5-3-en-082022.pdf#page=24

Note: For all shown regex, whitespace should be stripped from the target prior to matching.

MarcoWel commented 1 year ago

Putting it together:

Carrier Type Length Example Data Regex
DHL Express Air Waybill AWB 10 3318810025 SerialNumber CheckDigit [0-9]{10}
License Plate JD... (GS1-128 SSCC/NVE) 20 JD012345678901234567 Prefix CountryCode ShipperId SerialNumber JD[0-9]{18}
License Plate JJD... (GS1-128 SSCC/NVE) 21 JJD012345678901234567 see above JJD[0-9]{18}
DHL Paket / Europaket (GS1-128 SSCC/NVE) 20 00341234567890123459 SerialNumber CheckDigit 0034[0-9]{16}
Weltpaket / Retoure 12 186718204451 SerialNumber CheckDigit [0-9]{12}
Paket International (UPU S10) 13 CO123456789DE ServiceType SerialNumber CheckDigit CountryCode C[A-Z]{1}[0-9]{9}DE
Deutsche Post Registered Mail International (UPU S10) 13 RC123456789DE ServiceType SerialNumber CheckDigit CountryCode R[A-Z]{1}[0-9]{9}DE
Franking ID 20 A20100001D00010AE9FF AdminCode ShipperId PostingId SerialNumber CheckDigit [A-F0-9]{20}

Checksum DHL Express Waybill

The check digit is calculated using the remainder (or modulus), which is the amount "left over" after performing the division of two integers which do not divide evenly. Example: Shipment ID MOD 7 e.g. 123456789 MOD 7 = 1

Source: https://cdn-dhlguide.pressidium.com/wp-content/uploads/2020/11/dhlis11_gls_technical_guide.pdf

Checksum DHL Express Piece Code License Plate (GS1-128 SSCC/NVE)

No check digit! More info on DHL Express License Plate Codes: https://www.slideshare.net/martintreder16/license-plate-the-iso-standard-for-transport-package-identifiers

Checksum DHL Paket / Europaket (GS1-128 SSCC/NVE)

The check digit is calculated according to the "Modulo 10, weighting 3131" procedure as follows:

1) The digits are alternately multiplied by 3 and 1 (starting with 3). 2) Then all the results are added to form the sum. 3) The check digit now results from the difference to the next full ten. 4) If the remainder is 0, and the difference to 10 is therefore 10, the check digit is 0.

Note: In a more mathematically elegant way, the check digit is determined by calculating modulo 10 from the sum of all products and subtracting the remainder from 10.

Source: https://www.paketda.de/firmenkunden/paket-pruefziffern.html

Check digit calculator: https://www.gs1.org/services/check-digit-calculator

Checksum DHL Weltpaket/Retoure:

The first 11 digits of the package number are multiplied alternately by 4 and 9 (starting with 4). Example for package number 20129845227: 2 x 4 = 8 0 x 9 = 0 1 x 4 = 4 2 x 9 = 18 9 x 4 = 36 8 x 9 = 72 4×4=16 5 x 9 = 45 2 x 4 = 8 2 x 9 = 18 7 x 4 = 28 All results are then added together to form the sum. 8+0+4+18+36+72+16+45+8+18+28 = 253

The check digit is the difference to the next full ten: 260 - 253 = 7 If the remainder is 0, and the difference to 10 is therefore 10, the check digit is 0.

Source: https://www.paketda.de/firmenkunden/paket-pruefziffern.html

Checksum Deutsche Post / DHL International (UPU S10)

Ignore the Service Indicator Code and Country Code Assign the weights 8, 6, 4, 2, 3, 5, 9, 7 to the 8 digits, from left to right Calculate S, the sum of each digit multiplied by its weight. For example, for the number 47312482, S = 48 + 76 + 34 + 12 + 23 + 45 + 89 + 27 = 200 Calculate the check digit, C, from C = 11 - (S mod 11) If C = 10, change to C = 0 If C = 11, change to C = 5 For the example 47312482 C = 11 - (200 mod 11) = 11 - 2 = 9.

Source: https://en.wikipedia.org/wiki/S10_(UPU_standard)

Checksum Deutsche Post Franking ID

A hexadecimal character between ‘0’ and ‘F’ is indicated as a check digit, the last character in the 20-place franking ID. The check digit is calculated using the Cyclic Redundancy Check (CRC), CCITT Type (CRC-4). For this calculation, the characters of the 19-place payload data of the franking ID in the sequence are converted into bytes, in accordance with the ASCII table. The bytes are subsequently converted into bits. The CRC4 calculation is applied to this bit stream. The result which, according to this process, is always a bit sequence with 4 bits is converted into a hexadecimal character for display in the franking ID and then printed as the final character.

Source: https://www.deutschepost.de/content/dam/dpag/images/D_d/DV-Freimachung/downloads/dp-dv-freimachung-mlfvm-1-5-3-en-082022.pdf#page=26

funwithbots commented 1 year ago

Can someone provide multiple examples of valid 20 character franking ID values for testing?