erajkhatiwada / imb
A lightweight PHP library for encoding and decoding USPS Intelligent Mail Barcodes (IMB)
Requires
- php: ^7.4 || ^8.0
Requires (Dev)
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.6 || ^10.0 || ^11.0
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2026-03-13 23:39:19 UTC
README
A lightweight PHP library for encoding and decoding USPS Intelligent Mail Barcodes (IMB).
Note: This is a PHP port/wrapper of the original Node.js library BossRoxall/imb created by BossRoxall. All credit for the original algorithm implementation goes to the original author.
Features
- Encode postal information into 65-character IMB barcode strings
- Decode IMB barcode strings back to postal data
- Error correction for damaged barcodes
- Full validation of input data
- CLI tool for command-line operations
- PSR-4 autoloading compatible
- PHPStan Level 8 compatible
- 100% test coverage ready
Installation
Via Composer
composer require erajkhatiwada/imb
Manual Installation
- Clone the repository
- Run
composer install
Quick Start
Encoding
<?php use Imb\IMB; // Encode with required fields only $barcode = IMB::encode([ 'barcode_id' => '01', 'service_type' => '234', 'mailer_id' => '567094', 'serial_num' => '987654321', ]); // Output: "ADFTATFTDTADTDAFF..." (65 characters) // Encode with full routing information $barcode = IMB::encode([ 'barcode_id' => '01', 'service_type' => '234', 'mailer_id' => '567094', 'serial_num' => '987654321', 'zip' => '12345', 'plus4' => '6789', 'delivery_pt' => '01', ]);
Decoding
<?php use Imb\IMB; $result = IMB::decode('ADFTATFTDTADTDAFF...'); echo $result->data->barcodeId; // "01" echo $result->data->serviceType; // "234" echo $result->data->mailerId; // "567094" echo $result->data->serialNum; // "987654321" echo $result->data->zip; // "12345" (if present) echo $result->data->plus4; // "6789" (if present) echo $result->data->deliveryPt; // "01" (if present) // Convert to array $array = IMB::decodeToArray('ADFTATFTDTADTDAFF...');
Validation
<?php use Imb\IMB; // Validate input data $isValid = IMB::validate([ 'barcode_id' => '01', 'service_type' => '234', 'mailer_id' => '567094', 'serial_num' => '987654321', ]); // Validate barcode string $isValid = IMB::validateBarcode('ADFTATFTDTADTDAFF...');
Stringify
Convert IMB data to a concatenated numeric string (useful for display or comparison):
<?php use Imb\IMB; // Get the raw numeric string representation $code = IMB::stringify([ 'barcode_id' => '00', 'service_type' => '270', 'mailer_id' => '103502', 'serial_num' => '017955971', 'zip' => '50310', 'plus4' => '1605', 'delivery_pt' => '15', ]); // Output: "0027010350201795597150310160515" (31 digits) // Without routing info (tracking only) $code = IMB::stringify([ 'barcode_id' => '01', 'service_type' => '234', 'mailer_id' => '567094', 'serial_num' => '987654321', ]); // Output: "01234567094987654321" (20 digits)
Input Fields
Required Fields
| Field | Description | Format |
|---|---|---|
barcode_id |
Barcode identifier | 2 digits, second digit must be 0-4 |
service_type |
Service type code | 3 digits |
mailer_id |
USPS mailer ID | 6 or 9 digits |
serial_num |
Serial number | Varies (mailer_id + serial_num = 15 digits) |
Optional Fields (Routing)
| Field | Description | Format |
|---|---|---|
zip |
ZIP code | 5 digits |
plus4 |
ZIP+4 extension | 4 digits (requires zip) |
delivery_pt |
Delivery point | 2 digits |
Output Format
The barcode is a 65-character string using only these characters:
- A - Ascending bar
- D - Descending bar
- F - Full bar (both ascending and descending)
- T - Track bar (neither ascending nor descending)
CLI Usage
The library includes a command-line interface:
# Show help ./bin/imb help # Encode ./bin/imb encode --barcode-id=01 --service-type=234 --mailer-id=567094 --serial-num=987654321 # Encode with routing ./bin/imb encode --barcode-id=01 --service-type=234 --mailer-id=567094 --serial-num=987654321 \ --zip=12345 --plus4=6789 --delivery-pt=01 # Decode ./bin/imb decode ADFTATFTDTADTDAFFADADTDAFDTDTFATDTDATDFDATDFDAFDTAFDAFDAFDAFDAFDA
Advanced Usage
Using IMBData Objects
<?php use Imb\IMB; use Imb\IMBData; // Create data object directly $data = new IMBData( '01', // barcodeId '234', // serviceType '567094', // mailerId '987654321', // serialNum '12345' // zip (optional) ); $barcode = IMB::encode($data); // Create from array (recommended) $data = IMBData::fromArray([ 'barcode_id' => '01', 'service_type' => '234', 'mailer_id' => '567094', 'serial_num' => '987654321', ]);
Using Encoder/Decoder Directly
<?php use Imb\Encoder; use Imb\Decoder; $encoder = new Encoder(); $decoder = new Decoder(); $barcode = $encoder->encode([...]); $result = $decoder->decode($barcode);
Error Handling
<?php use Imb\IMB; use Imb\Exception\ValidationException; use Imb\Exception\DecodingException; try { $barcode = IMB::encode([...]); } catch (ValidationException $e) { echo "Invalid input: " . $e->getMessage(); } try { $result = IMB::decode('invalid-barcode'); } catch (DecodingException $e) { echo "Could not decode: " . $e->getMessage(); }
Damaged Barcode Recovery
The decoder can attempt to recover damaged barcodes:
<?php use Imb\IMB; $result = IMB::decode($damagedBarcode); if ($result->wasDamaged()) { echo "Barcode was damaged and repaired"; echo "Suggested correction: " . $result->suggest; // $result->highlight shows which positions were corrected }
API Reference
IMB (Static Facade)
| Method | Description |
|---|---|
encode(array|IMBData $data): string |
Encode to barcode |
decode(string $barcode): DecodeResult |
Decode barcode |
decodeToArray(string $barcode): array |
Decode to array |
validate(array|IMBData $data): bool |
Validate input data |
validateBarcode(string $barcode): bool |
Validate barcode string |
stringify(array|IMBData $data): string |
Convert to numeric string |
createData(array $data): IMBData |
Create IMBData object |
getEncoder(): Encoder |
Get encoder instance |
getDecoder(): Decoder |
Get decoder instance |
IMBData
| Property | Type | Description |
|---|---|---|
barcodeId |
string | 2-digit barcode ID |
serviceType |
string | 3-digit service type |
mailerId |
string | 6 or 9 digit mailer ID |
serialNum |
string | Serial number |
zip |
?string | 5-digit ZIP |
plus4 |
?string | 4-digit ZIP+4 |
deliveryPt |
?string | 2-digit delivery point |
| Method | Description |
|---|---|
fromArray(array $data): IMBData |
Create from associative array |
toArray(): array |
Convert to associative array |
stringify(): string |
Convert to concatenated numeric string |
getMailerIdLength(): int |
Get mailer ID length (6 or 9) |
hasNineDigitMailerId(): bool |
Check if 9-digit mailer ID |
DecodeResult
| Property | Type | Description |
|---|---|---|
data |
IMBData | Decoded data |
message |
?string | Status message |
suggest |
?string | Suggested correction |
highlight |
?array | Positions that differ |
Testing
# Run all tests composer test # Run with coverage composer test-coverage # Run PHPStan composer phpstan # Run code style check composer cs # Run all checks composer check
Requirements
- PHP 7.4 or higher
- No external dependencies for runtime
- PHPUnit 9.6+ for testing (dev)
License
This project is released under the CC0 1.0 Universal (Public Domain) license, same as the original Node.js library.
Acknowledgments
This PHP library is a direct port of the excellent Node.js IMB library created by BossRoxall. The encoding/decoding algorithms, bit permutation tables, and overall architecture are derived from that original work.
Special thanks to:
- BossRoxall - Author of the original Node.js IMB library
- Bob Codes - Original IMB algorithm implementation (released under CC0)
- USPS - Intelligent Mail Barcode specification
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Related Projects
- BossRoxall/imb - Original Node.js implementation (the source of this port)