EAN-13 編碼規則
- 13 位數字:前 12 位資料 + 第 13 位檢查碼
- 左半邊 6 碼:依首碼決定 A/B 編碼模式
- 右半邊 6 碼:固定 C 編碼
- 檢查碼計算:奇數位和 × 3 + 偶數位和,取 10 的補數
完整 GD 繪圖實作
<?php
function generateEAN13(string $code, int $barWidth = 2, int $height = 100): void {
// 1. 驗證輸入
if (strlen($code) !== 13 || !ctype_digit($code)) {
throw new InvalidArgumentException('EAN-13 必須為 13 位數字');
}
if (!verifyChecksum($code)) {
throw new InvalidArgumentException('檢查碼錯誤');
}
// 2. 編碼表
$Lencode = [
'A' => ['0001101','0011001','0010011','0111101','0100011','0110001','0101111','0111011','0110111','0001011'],
'B' => ['0100111','0110011','0011011','0100001','0011101','0111001','0000101','0010001','0001001','0010111'],
];
$Rencode = ['1110010','1100110','1101100','1000010','1011100','1001110','1010000','1000100','1001000','1110100'];
$patterns = ['AAAAAA','AABABB','AABBAB','ABAABB','ABBAAB','ABBBAA','ABABAB','ABABBA','ABBABA'];
// 3. 建構條碼二進位字串
$barcode = '101'; // 左護衛條
$firstDigit = (int)$code[0];
$pattern = $patterns[$firstDigit];
for ($i = 1; $i <= 6; $i++) {
$type = $pattern[$i - 1]; // A 或 B
$digit = (int)$code[$i];
$barcode .= $Lencode[$type][$digit];
}
$barcode .= '01010'; // 中護衛條
for ($i = 7; $i < 13; $i++) {
$barcode .= $Rencode[(int)$code[$i]];
}
$barcode .= '101'; // 右護衛條
// 4. GD 繪圖
$totalWidth = strlen($barcode) * $barWidth;
$imgWidth = $totalWidth + 60; // 左右留白
$imgHeight = $height + 40; // 底部留白給文字
$img = imagecreatetruecolor($imgWidth, $imgHeight);
$white = imagecolorallocate($img, 255, 255, 255);
$black = imagecolorallocate($img, 0, 0, 0);
imagefill($img, 0, 0, $white);
// 繪製條碼
$xOffset = 30;
for ($x = 0; $x < strlen($barcode); $x++) {
$barH = $height;
// 護衛條加高
if ($x < 3 || ($x >= 45 && $x < 50) || $x >= 92) {
$barH += 10;
}
if ($barcode[$x] === '1') {
imagefilledrectangle($img, $xOffset + $x * $barWidth, 5,
$xOffset + ($x + 1) * $barWidth - 1, 5 + $barH, $black);
}
}
// 繪製數字
$font = 5; // 內建字體
// 首碼置左
imagestring($img, $font, 10, $height + 10, $code[0], $black);
// 左 6 碼
for ($i = 0; $i < 6; $i++) {
imagestring($img, $font, $xOffset + (8 + $i * 6) * $barWidth, $height + 10, $code[$i + 1], $black);
}
// 右 6 碼
for ($i = 0; $i < 6; $i++) {
imagestring($img, $font, $xOffset + (53 + $i * 6) * $barWidth, $height + 10, $code[$i + 7], $black);
}
// 5. 輸出
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
}
function verifyChecksum(string $code): bool {
$sum = 0;
for ($i = 0; $i < 12; $i++) {
$sum += ($i % 2 === 0) ? (int)$code[$i] * 3 : (int)$code[$i];
}
$check = (10 - ($sum % 10)) % 10;
return $check === (int)$code[12];
}
// 使用
generateEAN13('6901028055048'); // 直接輸出 PNG
儲存檔案而非直接輸出
<?php
function saveEAN13(string $code, string $filename, int $barWidth = 2, int $height = 100): void {
// ... 前面邏輯相同,最後:
imagepng($img, $filename);
imagedestroy($img);
}
saveEAN13('6901028055048', 'barcode.png');
進階:支援更多條碼格式
| 格式 | 長度 | 用途 | PHP 庫推薦 |
| EAN-13 | 13 | 商品零售 | 自實作 / Picqer/Barcode |
| EAN-8 | 8 | 小包裝商品 | Picqer/Barcode |
| UPC-A | 12 | 北美零售 | Picqer/Barcode |
| Code 128 | 可變 | 物流/倉儲 | Picqer/Barcode |
| QR Code | 可變 | 行動應用 | endroid/qr-code |
Composer 庫推薦(生產環境)
composer require picqer/php-barcode-generator
<?php
use Picqer\Barcode\BarcodeGeneratorPNG;
$generator = new BarcodeGeneratorPNG();
file_put_contents('ean13.png', $generator->getBarcode('6901028055048', $generator::TYPE_EAN_13));
// 內建驗證、多格式、可調整尺寸/字體
- 上一篇文章: PHP 堆積排序 實作與效能測試
- 下一篇文章: PHP 計算排列組合:笛卡兒積與多維陣列遍歷
Copyright ©
程式碼之家 All Rights Reserved