Engineering tools · EPC · GS1
RFID Code Converter
Converter tool between SGTIN-96 (RFID Hex) and Barcode (GTIN) + Serial Number. Compatible with standard RFID readers like Zebra, Chainway, Impinj, Nextwaves. Based on GS1 EPC Tag Data Standard.
RFID Converter
Convert between RFID Hex (SGTIN-96) and GS1 Barcode (GTIN) + Serial Number.
Scheme:SGTIN-9696 bits / Header 0x30
EPC URIs
Code Logic & Step-by-Step
// 1. Binary Conversion
src = bin(0x3076215F0C5D974000000001) // = "001100000111011000100001010111110000110001011101100101110100000000000000000000000000000000000001"
// 2. Extract Fields (Bit Slice)
header = src[0:8] "00110000" 0x30
filter = src[8:11] "011" 3
partition = src[11:14] "101" 5
// 3. Determine Partition Rule (Partition 5)
rule = PARTITIONS[5]
// Company Bits: 24, Item Bits: 20// 4. Extract Company, Item & Serial
company = src[14:38] "100010000101011111000011" 8935363
itemRef = src[38:58] "00010111011001011101" 095837
serial = src[58:96] "00000000000000000000000000000000000001" 1
Developer Code
Use this utility logic in your project. Select a language below.
1// TypeScript / JavaScript SGTIN-96 Utils
2
3export const GS1_PARTITION_TABLE = [
4 { value: 0, partition: 0, companyPrefixBits: 40, itemReferenceBits: 4, companyDigits: 12, itemDigits: 1 },
5 { value: 1, partition: 1, companyPrefixBits: 37, itemReferenceBits: 7, companyDigits: 11, itemDigits: 2 },
6 { value: 2, partition: 2, companyPrefixBits: 34, itemReferenceBits: 10, companyDigits: 10, itemDigits: 3 },
7 { value: 3, partition: 3, companyPrefixBits: 30, itemReferenceBits: 14, companyDigits: 9, itemDigits: 4 },
8 { value: 4, partition: 4, companyPrefixBits: 27, itemReferenceBits: 17, companyDigits: 8, itemDigits: 5 },
9 { value: 5, partition: 5, companyPrefixBits: 24, itemReferenceBits: 20, companyDigits: 7, itemDigits: 6 },
10 { value: 6, partition: 6, companyPrefixBits: 20, itemReferenceBits: 24, companyDigits: 6, itemDigits: 7 },
11];
12
13export function encodeSgtin96(gtin: string, serial: string, filter: number) {
14 gtin = gtin.padStart(14, "0");
15 const p = GS1_PARTITION_TABLE.find(rule => {
16 const cp = parseInt(gtin.slice(1, 1 + rule.companyDigits));
17 const ir = parseInt(gtin[0] + gtin.slice(1 + rule.companyDigits, 13));
18 return cp < (1 << rule.companyPrefixBits) && ir < (1 << rule.itemReferenceBits);
19 });
20 if (!p) throw new Error("Invalid GTIN for SGTIN-96");
21
22 const cpVal = parseInt(gtin.slice(1, 1 + p.companyDigits));
23 const irVal = parseInt(gtin[0] + gtin.slice(1 + p.companyDigits, 13));
24
25 let b = (0x30).toString(2).padStart(8,"0");
26 b += filter.toString(2).padStart(3,"0");
27 b += p.partition.toString(2).padStart(3,"0");
28 b += cpVal.toString(2).padStart(p.companyPrefixBits,"0");
29 b += irVal.toString(2).padStart(p.itemReferenceBits,"0");
30 b += parseInt(serial).toString(2).padStart(38,"0");
31 return binaryToHex(b);
32}
33
34export function decodeSgtin96(hex: string) {
35 const b = hexToBinary(hex);
36 const pVal = parseInt(b.substring(11, 14), 2);
37 const rule = GS1_PARTITION_TABLE.find(r => r.partition === pVal);
38 if (!rule) throw new Error("Invalid Partition");
39
40 const cp = parseInt(b.substring(14, 14 + rule.companyPrefixBits), 2);
41 const ir = parseInt(b.substring(14 + rule.companyPrefixBits, 14 + rule.companyPrefixBits + rule.itemReferenceBits), 2);
42 const serial = parseInt(b.substring(14 + rule.companyPrefixBits + rule.itemReferenceBits, 96), 2);
43
44 const cpStr = cp.toString().padStart(rule.companyDigits, "0");
45 const irStr = ir.toString().padStart(rule.itemDigits, "0");
46 const gtinCore = irStr[0] + cpStr + irStr.substring(1);
47
48 // Check digit calculation
49 let sum = 0;
50 for (let i = 0; i < 13; i++) {
51 sum += parseInt(gtinCore[i]) * (i % 2 === 0 ? 3 : 1);
52 }
53 const check = (10 - (sum % 10)) % 10;
54
55 return {
56 gtin: gtinCore + check,
57 serial: serial.toString()
58 };
59}
60
61function binaryToHex(b: string) {
62 let hex = "";
63 for (let i = 0; i < b.length; i += 4) {
64 hex += parseInt(b.substring(i, i + 4), 2).toString(16).toUpperCase();
65 }
66 return hex;
67}
68
69function hexToBinary(h: string) {
70 let bin = "";
71 for (let i = 0; i < h.length; i++) {
72 bin += parseInt(h[i], 16).toString(2).padStart(4, "0");
73 }
74 return bin;
75}Explain
SGTIN-96 is a 96-bit binary string divided into 6 parts:
HDRFLTPRTCMP (24)ITEM (20)SERIAL (38)
Header (8 bit)Bits 0-8 (8)
001100000x30Standard prefix (00110000) identifying this as SGTIN-96.
Filter (3 bit)Bits 8-11 (3)
0113Object type (e.g. 1 = Retail Retail). See Reference Guide below.
Partition (3 bit)Bits 11-14 (3)
1015Partition 5 means: Company Code takes 24 bits, Product Code takes 20 bits.
Company PrefixBits 14-38 (24)
1000100001010111110000118935363Unique company code assigned by GS1.
Item ReferenceBits 38-58 (20)
00010111011001011101095837Your specific product code.
Serial Number (38 bit)Bits 58-96 (38)
000000000000000000000000000000000000011Unique identifier for each specific physical product.
Understanding SGTIN & GTIN
Visualizing the relationship between your physical barcode and the electronic product code (EPC).

Encoding Logic (Step-by-Step)
- Step 1: Determine the binary header value for the EPC schema. The binary header value for SGTIN-96 is “00110000.”
- Step 2: Select the Partition Value based on the number of digits in the Company Prefix from the Partition Value Table.
- Step 3: Convert the Filter Value, Partition Value, Company Prefix, Item Reference, and Serial # to binary value.
- Step 4: Concatenate in order Header, Filter, Partition, Company Prefix, Item Reference, and Serial # binary values to form the Binary EPC.
SGTIN-96 Reference Guide
| Value | Description |
|---|---|
| 0 | All Others Used for items that do not fit other categories. Rarely used in general retail. |
| 1 | Point of Sale (POS) Trade Item The standard consumer unit sold at Point of Sale. Example: A single bottle of shampoo. |
| 2 | Full Case for Transport A standard shipping unit containing multiple items. Example: A carton of 12 shampoo bottles. Critical for logistics to distinguish 'one case' from 'one item'. |
| 3 | Reserved Reserved for future use. |
| 4 | Inner Pack Trade Item Grouping A grouping smaller than a full case, often for shelf display or handling. Example: A shrink-wrapped 3-pack inside the main carton. |
| 5 | Reserved Reserved for future use. |
| 6 | Unit Load A large logistical unit, typically a pallet containing multiple cases. |
| 7 | Component inside Consumer Unit A specific part inside a consumer unit. Example: The battery cover inside a toy. |
| Value | Company Prefix | Item Reference |
|---|---|---|
| 0 | 40 Bits / 12 Digits | 4 Bits / 1 Digits |
| 1 | 37 Bits / 11 Digits | 7 Bits / 2 Digits |
| 2 | 34 Bits / 10 Digits | 10 Bits / 3 Digits |
| 3 | 30 Bits / 9 Digits | 14 Bits / 4 Digits |
| 4 | 27 Bits / 8 Digits | 17 Bits / 5 Digits |
| 5 | 24 Bits / 7 Digits | 20 Bits / 6 Digits |
| 6 | 20 Bits / 6 Digits | 24 Bits / 7 Digits |
SGTIN-96 Frequently Asked Questions
- It tells the system the packaging level of the tag. If a system reads a 'Case' tag (Filter 2), it knows it contains multiple items. This prevents double-counting (e.g., counting a case as just one single unit) and allows for valid shipping verification.
- Case (Filter 2) is the primary shipping unit used for transport. Inner Pack (Filter 4) is a subdivision inside that case, usually for easier handling or display (like a 6-pack inside a 24-can case). Logistics systems track Cases; Store operations might efficiently handle Inner Packs.
- The decoding will fail or produce the wrong Barcode. The Partition determines exactly where the Company Prefix ends and the Item Reference begins. If this 'split point' is wrong, you will get a different Company Code than intended.
- Standard GTIN (Barcode) only identifies the product type (e.g., '12oz Soda'). SGTIN-96 adds a Serial Number, giving every single can a unique identity. This enables item-level traceability, allowing you to track exactly which specific item was sold, stolen, or expired.
- Yes. As shown in the converter above, the SGTIN-96 string contains the complete GTIN-14. By removing the Serial Number and header information, you can perfectly reconstruct the original retail barcode.
- The Header (0x30) is a standard 8-bit prefix defined by GS1. It simply tells any RFID reader: "This tag is encoded using the SGTIN-96 standard." Other headers exist for different standards (like SSCC for pallets or GIAI for assets).