バーコードの仕様がなかなかのカオスだった話

# バーコードの仕様
今、お仕事でAndroidでバーコードを読み取って、在庫管理するアプリを作っているのですが、その中で得たノウハウ、バーコードの仕様がなかなかのカオスだったので紹介します。
## バーコードの種類
世界にはバーコードの種類がどのくらいあるか、ご存知でしょうか？100種類以上あります。それぞれの見た目によって、綺麗に仕様が別れているのかと言うと・・・そうでもなく。
* 符号化(内部表現の文字列をバーに変換する仕様)
* コード化(内部表現の文字列)の仕様
* アプリケーションレベルの仕様(内部表現の文字列が何を、どう表現しているのか)
* 途中で仕様の呼び名が変わっている
* メーカによって、呼び名、サポートしている種類の範囲が微妙に異なる

等など、これらがの仕様一緒になった仕様もあれば一部分だけの仕様もあり、更に既にある仕様を元に拡張した仕様、等など・・なかなかのカオス状態です。
おそらく、バーコードの歴史からすると最初はバーコードを読み取るリーダの方の性能もさほど高くなく、最低限の機能で始まって、そのうちリーダの性能も上がり、色々なものをバーコードに表現したいという要望があり、どんどん拡張、種類も増えていったのだと思います。

バーコードは大きくわけて1次元と2次元バーコードがあります。1次元は横にバーコードが伸びているやつですが、1次元でもそれが2段になっているものもあります。2次元はQRバーコードがお馴染み(LINEの友だち追加とかでも使われる、URLとかのやりとりでも使われる)ですが、QRバーコード以外にもあります。

* 1次元バーコード(代表的なものだけ)
  * JAN・EAN/UPC
  * ITF
  * CODE39
  * NW-7
  * CODE128 
* 2次元バーコード(代表的なものだけ)
  * QRバーコード(みなさま、お馴染みのやつです。)
  * GS1 DataMatrix(QRに似てるけどちょっと違う。3つの隅に四角マークがない)
  * PDF417(1次元のようだけど、列が別れている)

参考URL：
バーコードの仕様/ノウハウに関しては謎の高年収企業として話題になった、キーエンスのホームページに詳しく乗っています。ユーザ登録するとPDFでダウンロードできます。また、キーエンスはバーコードリーダを搭載した専用端末、Android端末を販売していますが、そのカメラ部分は専用設計で、普通一般ではみたことのない専用設計カメラです。なので、バーコードの読み取り性能は業界でピカイチ。他の、メーカのバーコードリーダでは読み取りエラーになるようなバーコードでも読み取れます。
* [バーコード講座(キーエンス)](keyence.co.jp/ss/products/autoid/codereader)

他のバーコード関連サイト
* [GS1のホームページ](https://www.gs1jp.org/)

バーコードを作成するツール
* [テスト用のバーコードを作るツール、BarCode作成管理くん](https://barcode-sakusei.jp.download.it/)
* [DataBar バーコード をオンラインで生成](https://products.aspose.app/barcode/ja/generate/databar)
* [バーコード作成ソフト SakuraBar for Windows Ver7.0](https://www.rolan.co.jp/shouhin/s_sakurabarcode5.html)

# 1次元バーコード
バーコードの仕様の詳細はキーエンスのホームページを参照してください。ここでは代表的なものと、それを拡張したものをいくつか紹介します。
## JAN/EAN/UPC
JANはみなさんご存ではないでしょうか。スーパなどのレジの精算で使われているアレですね。内部表現としては数字のみ13桁、または8桁で、基本的に**どの企業のどの商品**までしか表現できません。
JANは国際的にはEANと呼ばれています。(呼び名が違うだけ)アメリカ/カナダで使われているUPCと互換性があります。なのでこの3つは同時に扱われる場合が多いです。
## CODE39
数字、アルファベット大文字、記号(一部)が使えます。桁数に制限はありません。なのでJAN/EAN/UPCよりも多くの表現ができます。
## CODE128
ASCIIコード全部(数字、アルファベット大文字/小文字、記号、制御文字)が使えます。桁数に制限はありません。CODE39より更に多くのものの表現ができます。(URLとかも可能)。**全角文字は使えませんので、日本語の表現はできません。**

## CODE128を拡張した1次元バーコードの仕様
上記をみると、CODE128が1次元バーコードで一番表現力が高いのがおわかりかと思います。このCODE128を拡張した1次元バーコードの仕様というのが複数存在します。この辺からだんだんカオスになってきます。
### GS1-128
GS1-128は符号化と内部表現の文字列はCODE128を使用しています。桁数に制限がないので、色々なものを表現できます。一般的に商品コードだけではなく、製造年月日、消費期限、製造ロット、その企業独自のコード、等など・・・流通業界において表現したいものは多々あります。
これらを表現する使用がGS1-128でなんですが、どちらかと言うとアプリケーションレベルの仕様(ローレベル、H/W仕様はCODE128)と言えます。その中で、
* 商品コード
* 製造年月日
* 消費期限
* 製造ロット
* その企業独自のコード
* 等など・・・

をどう表現するかですが、AI(アプリケーション識別子)を用いて行います。このAIの仕様は
[GS1 Japan AIを正しく実装するためのポイント（プリンター、スキャナーメーカー様向け）](https://www.gs1jp.org/standard/identify/ai/explanation07.html)
[GS1アプリケーション識別子(AI)リスト
(GS1 Application Identifiers)
2022年8月](https://www.gs1jp.org/assets/img/pdf/GS1_Application_Identifiers_2103.pdf)
を参照してください。ここで説明しておきたいのは・・・
![ai_data10-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/3705f804-e86f-9cde-aa46-841773929302.png)

AI(カッコで括られている(01)とか(10)とか、(21)とか)によって、それに続く文字列が何の意味を持っているのかを表現します。上の例だと
* (01)はGTIN(商品コード)
* (10)はロット番号
* (21)はシリアル番号

を表現しています。これだけを見ると、はは、なるほど、簡単な表示じゃん・・・と思うかもしれませんが、上のAIの仕様のURLを見てください。AIは2桁とは決まっておらず、2〜4桁まであります。AIに続く文字列ですが、固定長のものもありますが、**可変長**のものもあります。しかも、上の例の印字の下側のコードではAIは( )で括られていますが、これは印刷上、そうしているだけで、実際のバーコードをバーコードリーダで読み取ると( )なしで、これらは全部繋がってひとつの文字列として取得されます。上の例だと
> 010491234567891110HH1026\<FNC1>21173421

となります。

**ん？区切り文字もないのか？可変長もあるのに、どうやって、分解してそれぞれのAIに続く値を取得するんだ？**

と、大抵の人が思うとおもいますが、上の図のAIが(10)の説明にもある通り可変長の場合はそのデータの最後に可変長のデータの終わりであることを示す制御文字(FNC1)を付加します。(uniodeで0x0000001d)

これによって、AIに続く文字列が固定長であっても可変長であっても、分解して取得できるようになっています。
が・・・記号/制御文字が使用可能なんだから、CSVみたいにAI毎に区切り記号を定義してくれれば、もっと楽なのに・・・と思う人は多いと思います。(自分もそう)なんで、こんな仕様なんでしょう？

### GS1-Databar(旧GS1-RSS)
GS1-RSS(Reduced Space Symbology(省スペースシンボル))を2007年2月に改称してGS1 Databarという名称になっています。(紛らわしい)
上のGS1-128と名称も似ているので何が違うのかわかりずらいです。もー、この辺からカオスです。
[医療分野における新バーコードGS1の基礎知識と在庫管理・トレーサビリティ](https://infusion.co.jp/zsc/column/gs1/#i-2)
[GS1 Databar(ジーエスワン データバー)とは？](https://www.barcode.ne.jp/barcode/1214.html)
あたりを見ると、GS1-128とGS1 Databarの違いは主に、医療分野で
| 包装の種類 | バーコード |
|:-:|:-:|
| 調剤包装  |  GS1 Databar |
| 販売包装  |  GS1 Databar |
| 元梱包装  |  GS1-128 |

と書かれています。表現しているデータが違うようですが、AI(アプリケーション識別子)を用いて、表現するデータの項目を分けているのは同じです。ちょっと、ここだけを見ると何が違うのか、よくわかりません。
![medical01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/22f58e0b-5ea8-ab9f-5420-ed811d1b8b57.png)
が、GS1 Databarは3タイプ7種類のシンボルに別れます。(ここが、GS1-128との違いなのか？この分け方も各情報を公開しているページによって異なる。もー、カオス)
* GTINのみを符号化するタイプ
  * GS1 Databar標準型(Omni-directional：オムニディレクショナル)
  * GS1 Databar二層型（Stacked：スタック）
  * GS1データバー 二層型
  * GS1 Databar カット型（Truncated：トランケート）
* 14桁で表示したGTINの先頭一桁が0か1のGTINのみを符号化する制約付きタイプ
  * GS1 Databar限定型 （Limited:：リミテッド）
* GTIN以外の属性情報を符号化するタイプ
  * GS1 Databar拡張型 （Expanded：エクスパンデッド）
  * GS1 Databar拡張多層型(Expanded Stacked：エクスパンデッド・スタック)

GS1 DatabarはGS1-128を包含しつつ、拡張した仕様のように思えますが・・・どうなんでしょう？はっきりとはかかれていません。また、GS1 Databarではバーコードが2段になった表示も定義されていますが、GS1-128では定義されていないように思えます。この辺の違いなのかもしれません。
### Composite(多段になっているバーコード)
GS1 Databarのところでも出てきましたが、多段になっているバーコードもあります。たぶん、どこかでみたことがあると思います。こんなやつです。
![05_GS1DataBar_Expanded_Stacked.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/c2a039f4-adec-b7ff-7b83-d73faf6fb7d5.png)
これも、Composite(多段)として別な仕様が定義されているのか、何か他の仕様を元に拡張してComposite(多段)の仕様を定義しているのか、よくわかりません。
キーエンスのAndroid端末では
* Composite AB(GS1-Databar)
* Composite AB(EAN/UPC)
* Composite AB(GS1-128)

が定義されていますが、正直、この辺になると、もーカオス過ぎて何が違うのかよくわかりません。
(既にある仕様を拡張して、Composite(多段)を定義しているようにも思えるが・・・)
# 2次元バーコード
## QRコード
お馴染みのLINEの友だち追加等で、使われるQRコードです。文字数、漢字(半角カナも可)、バイナリも使えるので近代的。色々な表現ができます。実はQRコードにも3種類の仕様があります。
### モデル1
下の2つの基本となっている仕様
| 文字の種類 | データ量 |
|:-:|:-:|
| 数字  | 1167字  |
| 英数字  | 707字  |
| バイナリ  | 468バイト  |
| 漢字  | 299文字  |

### モデル2
モデル1から拡張され大容量データに対応しています。
| 文字の種類 | データ量 |
|:-:|:-:|
| 数字  | 7089字  |
| 英数字  | 4296字  |
| バイナリ  | 2953バイト  |
| 漢字  | 1817文字  |

### マイクロQR
小さな印字スペースに印字できる仕様
| 文字の種類 | データ量 |
|:-:|:-:|
| 数字  | 35字  |
| 英数字  | 21字  |
| バイナリ  | 15バイト  |
| 漢字  | 9文字  |

## GS1 DataMatrix
名前の頭に「GS1」と付くので1次元のGS1-128、GS1 Databarと絡んでいるような、いないような・・・
QRコードと似ているようで、ちょっと違う(3つの隅に四角がない)こんなのは見たことがあると思います。
![Screenshot_20221204_173019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933408/d2ea1470-bea7-d3e6-e761-422f95e9c3b9.png)
内部のデータ表現はGS1-128、GS1 Databarと同じ様にAI(アプリケーション識別子)を用いています。

# GTINコードとJANコード
GS-128のところでも出てきました、商品を示すAI(01)のGTINコード(Global Trade Item Number)ですが、14桁で表現されます。このGTINコードの先頭1桁は集合包装商品用コードと定義されています。
| 集合包装商品用コード | 意味 |
|:-:|:-:|
| 1〜8  | 同一商品で荷姿が異なる。入り数が異なる。内箱と外箱の区別が必要。など  |
| 9  | 計量商品用(アドオンが付加されている)  |
| 0  | 集合包装(ダンボール)を 1つの商品として識別する場合  |

先頭のこの集合包装商品用コード、末尾のチェックデジットを除いて12桁はJANコードとなっています。
つまりGTINコード→JANコードには変換可能となります。

# 最後に
以上、なかなかカオスなバーコードの仕様を説明しました。これらの仕様もサイトやメーカによって微妙に表現がことなったりして、わかりずらいものもあります。仕様も年々改定されているのかもしれません。ここにないバーコードも日本で流通しているものもあります。何かの参考になれば幸いです。