decode static method

String? decode(
  1. String epcHex
)

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;
}