私のバーコード。Code128

生産活動の過程で、code128標準に従ってバーコードを生成する必要がありました。これは、使用中の関数(Oracleデータベースのストアドプロシージャ)が、すべての場合に読み取れるわけではない、クールなストライプのバーコードを生成したために発生しました。開発者はかつてこの手順を非常に不十分にテストしましたが、もはやそれをリサイクルするつもりはありませんでした。プロジェクトはかなり前に完了しましたが、読む必要はありませんでした。





最初に考えたのは、既製のライブラリを検索することです。箱から出して、基準を定義しました-pl / sqlに連絡せず、外部サービスにします:おそらくページ上で直接生成するJavaScriptの一部、またはphpがある最寄りのサーバーへの画像のリクエスト利用可能です。インターネットですばやく検索すると、トピックが非常に緊密に踏みにじられていることがわかりました。プログラミングラボレベルのニーハイの手工芸品と、QRコードまでのすべてのコーディングオプション用の強力なライブラリの両方があります。 JavaScriptオプションは削除する必要がありました。第一に、それらのほとんどすべてが「難読化」されており(音量を下げることも理解できないか、ソースコードを表示するのは残念です)、第二に、特定のフォントで表示するための文字列を生成します。そのうち、クライアントサイトで常に提供できるとは限らず、特殊文字をエスケープする追加の処理が必要です。ライブラリとphpコードの断片を注意深く研究したことも痛い印象を与えました-一見、すべてが正しいように見えます:クラスはあらゆる機会に書かれ、コメントが利用可能であり、色やフレームの選択などの装飾、例が用意されています。あなたは掘り下げ始めます-彼らは最新バージョンのphpを望んでいるか(戦闘サーバーでこれを取得することが常に可能であるとは限りません)、内部ロジックがまったく認識できないか、出力バーコードがより長いことが判明します期待されます。これが最後の悩みの種であり、彼ら自身の認識に追いやられました。あなたは掘り下げ始めます-彼らは最新バージョンのphpを望んでいるか(戦闘サーバーでこれを取得することが常に可能であるとは限りません)、内部ロジックがまったく認識できないか、出力バーコードがより長いことが判明します期待されます。これが最後の悩みの種であり、彼ら自身の認識に追いやられています。あなたは掘り下げ始めます-彼らは最新バージョンのphpを望んでいるか(戦闘サーバーでこれを取得することが常に可能であるとは限りません)、内部ロジックがまったく認識できないか、出力バーコードがより長いことが判明します期待されます。これが最後の悩みの種であり、彼ら自身の認識に追いやられました。





理論の感触をつかむ時が来ました。むしろ、私たちはずっと早く彼女に会いました。最近まで追加のプログラミングに関与したくなかっただけです。歴史的な事実は省略しますが、非常に優れた技術的な説明はhttp://code128.narod.ru/(ファイルDescript.docはアーカイブにあります)またはウィキペディアで入手できます。原則として、これが私たち自身のアルゴリズムを理解して実装するために必要なすべてです(ここで私は少し狡猾です-手動でドライブしないように、既製のライブラリからストローク幅のテーブルを取り除く必要があります)。さて、私たちはこのすべての恥辱をphpで書きます。同時に、誰もが忘れたり、使うのが恥ずかしい、いくつかのクールな瞬間を見るでしょう。





, code128 (!) 128 , 3 , . «B» - «» , — 2 . php- — «». .





— , . - . — . , .





. «ABC12DE» , B, - B :





- 1 . , 6 . — , , — ? , , .





, — () . . — , () ( 2- «»). , , ! «B» «C» - :)





, - B , . — , , . , :





<?php

class code128 {
    private $code = '';
    private $leafB = NULL, $leafC = NULL;

    public function __construct($text, $mode = 'B')
    {
			if (strlen($text) == 0) return NULL;

			$this->mode = $mode;

			if ($mode == 'B') {
	    		$this->code = substr($text, 0, 1);
	    		$text = substr($text, 1);
			}
			else if ($mode == 'C') {
	    		if (strlen($text) < 2) return NULL;
	    		if (!is_numeric($text[0])) return NULL;
	    		if (!is_numeric($text[1])) return NULL;

	    		$this->code = substr($text, 0, 2);
	    		$text = substr($text, 2);
			}
			else	
	    		return NULL;

			$this->leafB = new code128($text, 'B');
			$this->leafC = new code128($text, 'C');
    }

    public function draw()
    {
				echo "Code [" . $this->code . "]\n";
				if ($this->leafB != NULL) $this->leafB->draw();
				if ($this->leafC != NULL) $this->leafC->draw();
    }
}

    $n = new code128('s92317lsdfa4324', 'B');
    $n->draw();
?>
      
      



— "" . NULL! , php . - . . :





    public function __construct($text, $mode = 'B')
    {
			$this->mode = $mode;

			if ($mode == 'B') {
	    		$this->code = substr($text, 0, 1);
	    		$text = substr($text, 1);
			}
			else if ($mode == 'C') {
	    		$this->code = substr($text, 0, 2);
	    		$text = substr($text, 2);
			}

			if(strlen($text)>0) $this->leafB = new code128($text, 'B');
			if(strlen($text)>1)
	    		if(is_numeric($text[0]) && is_numeric($text[1])) $this->leafC = new code128($text, 'C');
    }

      
      



, , . - : , , .. . code128? , , , :





	if($mode == 'B') list($this->code, $text) = sscanf($text, '%c%s');
	if($mode == 'C') list($this->code, $text) = sscanf($text, '%2d%s');

	if(strlen($text)>0)
	    if(array_key_exists(substr($text, 0, 1), $symCode)) $this->leafB = new code128($text, 'B', $this);
	if(strlen($text)>1)
	    if(array_key_exists(substr($text, 0, 2), $symCode)) $this->leafC = new code128($text, 'C', $this);
      
      



$symCode - , tables.php require . - => .





$symCode = array(
/*	alphabet B	alphabet C */
	' ' => 0,	'00' => 0,
	'!' => 1,	'01' => 1,
	'"' => 2,	'02' => 2,
	'#' => 3,	'03' => 3,
	'$' => 4,	'04' => 4,
	'%' => 5,	'05' => 5,
	'&' => 6,	'06' => 6,

      
      



, . : - . ( ), . — 1, 1 2 . 2? . . . ? — « » . — . — , , . — , . , - :)





require 'tables.php';

class code128 {
    private $code = NULL;
    private $text = '';
    private $mode = 'Auto';
    private $len = 1;
    private $leafB = NULL, $leafC = NULL, $parent = NULL, $minCode = NULL;

    public function __construct($text, $mode = 'Auto', $parent = NULL)
    {
			global $symCode;
			$this->parent = $parent;
			$this->text = $text;
			$this->mode = $mode;

			if($parent != NULL) {
	    		$this->len = $this->parent->len + 1;
	    		if($this->parent->mode != $mode) $this->len++;
	     }

	    if($mode == 'B') list($this->code, $text) = sscanf($text, '%c%s');
	    if($mode == 'C') list($this->code, $text) = sscanf($text, '%2d%s');

	    if(strlen($text)>0)
	       if(array_key_exists(substr($text, 0, 1), $symCode)) $this->leafB = new code128($text, 'B', $this);
	    if(strlen($text)>1)
	       if(array_key_exists(substr($text, 0, 2), $symCode)) $this->leafC = new code128($text, 'C', $this);

	    if($this->leafB == NULL && $this->leafC == NULL) $this->minCode = $this;
	    else {
	       $this->minCode = ($this->leafB != NULL) ? $this->leafB->minCode : $this->leafC->minCode;
	       if($this->leafC != NULL)
		        if($this->minCode->len > $this->leafC->minCode->len) $this->minCode = $this->leafC->minCode;
	    }

	    return $this;
     }

      
      



, - (). . : . , , (push) . , PHP , .





 private function getCode()
 {
		$stack = array();
		$p = $this->minCode;

		while($p != NULL) {
	    	array_push($stack, $p->code);

	    	if($p->parent != NULL) {
						if($p->parent->mode == 'Auto') { array_push($stack, 'Start'.$p->mode); break;}
						if($p->mode != $p->parent->mode) array_push($stack, 'Code'.$p->mode);
	    	}

	    	$p = $p->parent;
		}

		return $stack;
  }
      
      



— array_pop. , . — // .





- , . . SVG. — , . , , dpi .





  private function printPattern($code, $posX, $res, $height)
  {
		for($i = 0; $i < strlen($code); $i++) {
	    	$w = $res*intval($code[$i]);

	    	if(!($i%2))
						echo "  <rect x='$posX' y='0' width='$w' height='$height' fill='#0'/>\n";

	    	$posX += $w;
			}

			return $posX;
   }

   public function printSVG($resolution=1, $height=50)
   {
			global $symCode;
			global $barPattern;

			$s = $this->getCode();

			$pos = 1;
			$offset = $resolution*11;
			$width = ((count($s) + 4)*11 + 2)*$resolution;

			echo "<svg xmlns='http://www.w3.org/2000/svg' width='$width' height='$height'>\n";

			$start = $symCode[array_pop($s)];
			$checksum = $start;

			$offset = $this->printPattern($barPattern[$start], $offset, $resolution, $height);

			while(!empty($s)) {
	    		$code = $symCode[array_pop($s)];
	    		$offset = $this->printPattern($barPattern[$code], $offset, $resolution, $height);
	    		$checksum += $code*$pos;
	    		$pos++;
			}

			$offset = $this->printPattern($barPattern[$checksum%103], $offset, $resolution, $height);
			$offset = $this->printPattern($barPattern[$symCode['Stop']], $offset, $resolution, $height);

			echo "</svg>\n";
    }

      
      



$barPattern. tables.php $symCode. . - :





$barPattern = array(
	'212222',	/* 0 */
	'222122',	/* 1 */
	'222221',	/* 2 */
	'121223',	/* 3 */
	'121322',	/* 4 */
      
      



? :





    header('Content-Type: image/svg+xml');
    echo "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n\n";

    $n = new code128(html_entity_decode($_SERVER["QUERY_STRING"]));
    $n->printSVG();
      
      



, html- :





<img src="barcode128.php?ad32324adsFAE13413ldsFf">
      
      



そして最後に。アルファベット「B」と「C」のみが実装されています。変換テーブルを除いて、約100行以内に保持されます。アルファベット「A」は、コンストラクターとアルファベットのテーブルを追加するだけで同様の方法で実装できますが、別のアルファベットの1つの文字に簡単に切り替えることができる1つのトリッキーなコードを考慮することをお勧めします。自分で書き終えたいという欲求、時間、その他の動機はありません。(半)完成したプロジェクトは、おそらくgithubのバーコードの墓地に追加されます-誰かがプロジェクトを継続したい場合は-遠慮なく書いてください。








All Articles