JANバーコードの仕様

POSレジで使われているJANコード(EANコード)について調べたので書き留めておきます。

## JANコードの仕様

JANコードには13桁の標準コードと8桁の短縮コードがある。
それぞれでバーコード化の仕方が少し異なる。

### 標準コード(13桁)
標準コードの場合以下の構成になっている。

先頭から**12桁がデータ**、**1桁がチェックデジット**になっている。

### 短縮コード(8桁)
短縮コードの場合以下の構成になっている。

先頭から**7桁がデータ**、**1桁がチェックデジット**になっている。

### チェックデジット
計算方法は以下の通り。

1. 最下位から見て奇数桁と偶数桁に分けて合計する  
2. 奇数桁を3倍し偶数桁と合計する
3. 10から1の位の値を減じる
4. 3.の値が10ならば0、それ以外ならばその値がチェックデジット

例) 490801153240

1. $4 + 0 + 0 + 1 + 3 + 4 = 12$ (偶数桁)  
$9 + 8 + 1 + 5 + 2 + 0 = 25$ (奇数桁)
2. $25 \times 3 + 12 = 87$
3. $10 - 7 = 3$
4. $3$

例) 4519176

1. $4 + 1 + 1 + 6 = 12$ (奇数桁)  
$5 + 9 + 7 = 21$ (偶数桁)
2. $12 \times 3 + 22 = 57$
3. $10 - 7 = 3$
4. $3$

## JANバーコードの仕様
![バーコード解説](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237007/f1dee515-dae1-46f8-927e-a0d4e9cfe9e9.png)

バーコードは左から

1. レフトマージン
2. レフトガードバー
3. レフトデータバー
4. センターバー
5. ライトデータバー チェックデジットバー
6. ライトガードバー
7. ライトマージン

に分かれている

### 単位
<dl>
  <dt>モジュール</dt>
  <dd>バーコードの1番細い線または空白が1モジュール</dd>
<br>
  <dt>キャラクタ</dt>
  <dd>数字1文字が1キャラクタ</dd>
</dl>

### 各部位(標準コード)
|部位|幅|説明|
|:-:|:-:|:-:|
|レフトマージン|11モジュール以上|左側の余白|
|レフトガードバー|3モジュール|左側の基準線|
|レフトデータバー|42モジュール<br>6キャラクタ|左側のデータ|
|センターバー|5モジュール|中央の基準線|
|ライトデータバー<br>チェックデジットバー|42モジュール<br>6キャラクタ|右側のデータ<br>チェックデジット|
|ライトガードバー|3モジュール|右側の基準線|
|ライトマージン|7モジュール以上|右側の余白|

### 各部位(短縮コード)
|部位|幅|説明|
|:-:|:-:|:-:|
|レフトマージン|7モジュール以上|左側の余白|
|レフトガードバー|3モジュール|左側の基準線|
|レフトデータバー|28モジュール<br>4キャラクタ|左側のデータ|
|センターバー|5モジュール|中央の基準線|
|ライトデータバー<br>チェックデジットバー|28モジュール<br>4キャラクタ|右側のデータ<br>チェックデジット|
|ライトガードバー|3モジュール|右側の基準線|
|ライトマージン|7モジュール以上|右側の余白|

### 符号化(標準コード)
最初の1桁目(プレフィックスキャラクタ)の数値に応じて奇数パリティまたは偶数パリティを組み合わせて用いて符号化する。

例) 4908011532403
1桁目(プレフィックスキャラクタ)が**4**だから**OEOOEE**で符号化する。
レフトデータバー**908011**、ライトデータバー**532403**に分割する。
下記の符号化テーブルに当てはめて符号化する。

レフトデータバー9: 左側のデータキャラクタ 奇数パリティ 9 -> **0001011**
レフトデータバー0: 左側のデータキャラクタ 偶数パリティ 0 -> **0100111**
レフトデータバー8: 左側のデータキャラクタ 奇数パリティ 8 -> **0110111**
...(中略)...
ライトデータバー4: 右側のデータキャラクタ 4 -> **1011100**
ライトデータバー0: 右側のデータキャラクタ 0 -> **1110010**
チェックデジットバー3: 右側のデータキャラクタ 3 -> **1000010**

レフトデータバー: 0001011_0100111_0110111_0001101_0110011_0110011
ライトデータバー: 1001110_1101100_1100110_1011100_1110010_1000010

左右のマージン、左右のガードバー、センターバーを含めて符号化する。

00000000000_101_000101101001110110111000110101100110110011_01010_100111011011001100110101110011100101000010_101_0000000

0を白、1を黒で画像化すると一般的なバーコードになる。
高さは適当に50pxとした。
![バーコード-4908011532403](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237007/b0cf3704-fc3c-58f8-dcd6-fa16dce429d1.png)


### 符号化(短縮コード)
奇数パリティを用いて符号化する。
短縮コードの場合はプレフィックスキャラクタを使わない。

例) 45191763
レフトデータバー**4519**、ライトデータバー**1763**に分割する。
下記の符号化テーブルに当てはめて符号化する。

レフトデータバー4: 左側のデータキャラクタ 奇数パリティ 4 -> **0100011**
レフトデータバー5: 左側のデータキャラクタ 奇数パリティ 5 -> **0110001**
レフトデータバー1: 左側のデータキャラクタ 奇数パリティ 1 -> **0011001**
...(中略)...
ライトデータバー7: 右側のデータキャラクタ 7 -> **1000100**
ライトデータバー6: 右側のデータキャラクタ 6 -> **1010000**
チェックデジットバー3: 右側のデータキャラクタ 3 -> **1000010**

レフトデータバー: 0100011_0110001_0011001_0111011
ライトデータバー: 1100110_1000100_1010000_1000010

左右のマージン、左右のガードバー、センターバーを含めて符号化する。

0000000_101_0100011011000100110010111011_01010_1100110100010010100001000010_101_0000000

0を白、1を黒で画像化すると一般的なバーコードになる。
高さは適当に50pxとした。
![バーコード-45191763](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237007/788920a2-855e-52c9-f23b-dfa7e79e6295.png)

### 符号化テーブル

|部位|ビット|
|:-:|:-:|
|空白|0|
|黒線|1|
|左右ガードバー|101|
|センターバー|01010|

|10進数|左側のデータキャラクタ<br>奇数パリティ|左側のデータキャラクタ<br>偶数パリティ|右側のデータキャラクタ|
|:-:|:-:|:-:|:-:|
|0|0001101|0100111|1110010|
|1|0011001|0110011|1100110|
|2|0010011|0011011|1101100|
|3|0111101|0100001|1000010|
|4|0100011|0011101|1011100|
|5|0110001|0111001|1001110|
|6|0101111|0000101|1010000|
|7|0111011|0010001|1000100|
|8|0110111|0001001|1001000|
|9|0001011|0010111|1110100|

|プレフィックスキャラクタ|データキャラクタの組み合わせ|
|:-:|:-:|
|0|OOOOOO|
|1|OOEOEE|
|2|OOEEOE|
|3|OOEEEO|
|4|OEOOEE|
|5|OEEOOE|
|6|OEEEOO|
|7|OEOEOE|
|8|OEOEEO|
|9|OEEOEO|
Oが奇数パリティ、Eが偶数パリティ

## JavaScriptでの実装例

<p data-height="512" data-theme-id="0" data-slug-hash="WNGmyRq" data-default-tab="js,result" data-user="dolphin0809" data-embed-version="2" data-pen-title="EAN/JAN Barcode" class="codepen">See the Pen <a href="https://codepen.io/dolphin0809/pen/WNGmyRq">EAN/JAN Barcode</a> by Dolphin (<a href="https://codepen.io/dolphin0809">@dolphin0809</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

## 参考資料

[JAN/EANコード規格  - バーコードとは？ - バーコード情報サイト（日栄インテック）](https://www.barcode.ne.jp/barcode/291.html) 2021/01/21 閲覧