decode static method
Decodes a SGTIN-96 EPC hex string to EAN-13. Returns null if the EPC is not a valid SGTIN-96.
Implementation
static String? decode(String epcHex) {
epcHex = epcHex.replaceAll(' ', '').toUpperCase();
if (epcHex.length != 24) return null;
final BigInt epc;
try {
epc = BigInt.parse(epcHex, radix: 16);
} catch (_) {
return null;
}
// Header (bits 95-88) must be 0x30 for SGTIN-96
final int header = _extractBits(epc, 95, 88);
if (header != 0x30) return null;
final int partition = _extractBits(epc, 84, 82);
if (partition > 6) return null;
final prefixBits = _partitionTable[partition][0];
final prefixDigits = _partitionTable[partition][1];
final itemRefBits = _partitionTable[partition][2];
final itemRefDigits = _partitionTable[partition][3];
final int companyPrefix = _extractBits(epc, 81, 81 - prefixBits + 1);
final int itemRefStart = 81 - prefixBits;
final int itemRef = _extractBits(
epc,
itemRefStart,
itemRefStart - itemRefBits + 1,
);
// indicator_digit * 10^(itemRefDigits-1) + actual_item_ref
final int indicatorDivisor = _pow10(itemRefDigits - 1);
final int indicator = itemRef ~/ indicatorDivisor;
final int actualItemRef = itemRef % indicatorDivisor;
// GTIN-13: indicator + companyPrefix + itemRef
final String prefixStr = companyPrefix.toString().padLeft(
prefixDigits,
'0',
);
final String itemRefStr = actualItemRef.toString().padLeft(
itemRefDigits - 1,
'0',
);
final String gtinWithoutCheck = '$indicator$prefixStr$itemRefStr';
if (gtinWithoutCheck.length != 13) return null;
final int checkDigit = _computeCheckDigit(gtinWithoutCheck.substring(1));
final String ean13 = '${gtinWithoutCheck.substring(1)}$checkDigit';
return ean13;
}