Kode batang saya. Kode128

Begitu dalam proses kegiatan produksi, saya harus membuat barcode sesuai dengan standar code128. Itu muncul karena fakta bahwa fungsi yang digunakan (prosedur tersimpan dalam database Oracle) menghasilkan barcode bergaris yang keren yang tidak dapat dibaca dalam semua kasus. Pengembang pada suatu waktu menguji prosedur ini dengan sangat buruk, tetapi mereka tidak lagi akan mendaur ulangnya. proyek sudah selesai sejak lama, tetapi kebutuhan untuk membaca tidak muncul.





Pikiran pertama adalah mencari perpustakaan yang sudah jadi. Di luar kotak, kami menetapkan kriteria - kami tidak menghubungi pl / sql, biarkan itu menjadi layanan eksternal: mungkin sepotong javascript untuk menghasilkan langsung di halaman, atau permintaan gambar ke server terdekat tempat php tersedia. Pencarian cepat di Internet menunjukkan bahwa topik itu diinjak-injak dengan sangat ketat. Ada kerajinan setinggi lutut dari tingkat laboratorium pemrograman, serta perpustakaan yang kuat untuk semua opsi pengkodean, hingga kode QR. Opsi JavaScript harus dihapus karena pertama, hampir semuanya "dikaburkan" (bahkan tidak dapat dipahami, baik untuk mengurangi volume, atau memalukan untuk menunjukkan kode sumber), dan kedua, mereka menghasilkan string untuk ditampilkan dalam font tertentu, kehadiran yang tidak selalu dapat disediakan di situs klien dan memerlukan pemrosesan tambahan yang keluar dari karakter khusus.Sebuah studi cermat perpustakaan dan potongan kode php juga membuat kesan yang menyakitkan - pada pandangan pertama, semuanya tampak benar: kelas ditulis untuk semua kesempatan, komentar tersedia, dekorasi seperti memilih warna dan bingkai, contoh telah disiapkan . Anda akan mulai menyelidiki - mereka menginginkan php dari versi terbaru (tidak selalu mungkin untuk mendapatkannya di server tempur), atau logika internal tidak terlihat sama sekali, atau kode batang keluaran ternyata lebih panjang dari diharapkan. Inilah yang terakhir dihantui dan didorong ke realisasi mereka sendiri.Anda akan mulai menyelidiki - mereka menginginkan php dari versi terbaru (tidak selalu mungkin untuk mendapatkannya di server tempur), atau logika internal tidak terlihat sama sekali, atau kode batang keluaran ternyata lebih panjang dari diharapkan. Inilah yang terakhir dihantui dan didorong ke realisasi mereka sendiri.Anda akan mulai menyelidiki - mereka menginginkan php dari versi terbaru (tidak selalu mungkin untuk mendapatkannya di server tempur), atau logika internal tidak terlihat sama sekali, atau kode batang keluaran ternyata lebih panjang dari diharapkan. Inilah yang terakhir dihantui dan didorong ke realisasi mereka sendiri.





Saatnya untuk merasakan teorinya. Sebaliknya, kami bertemu dengannya lebih awal, kami hanya tidak ingin terlibat dalam pemrograman tambahan sampai saat ini. Kami akan menghilangkan fakta sejarah, tetapi deskripsi teknis yang sangat baik tersedia di http://code128.narod.ru/ (file Descript.doc ada di arsip ) atau di Wikipedia. Pada prinsipnya, hanya ini yang perlu kita pahami dan terapkan algoritma kita sendiri (di sini saya sedikit licik - Anda perlu merobek tabel lebar goresan dari perpustakaan yang sudah jadi agar tidak memasukkannya secara manual). Nah, kita akan menulis semua aib ini di php, pada saat yang sama kita akan melihat beberapa momen keren yang semua orang lupa atau malu untuk menggunakannya.





, 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">
      
      



Dan akhirnya. Hanya huruf "B" dan "C" yang diterapkan. Disimpan dalam sekitar 100 baris, tidak termasuk tabel konversi. Alfabet "A" dapat diimplementasikan dengan cara yang sama, cukup dengan menambahkan konstruktor dan tabel dengan alfabet, tetapi disarankan untuk mempertimbangkan satu kode rumit yang memungkinkan Anda untuk secara singkat beralih ke satu karakter alfabet yang berbeda. Saya tidak punya keinginan, waktu, atau motivasi lain untuk menyelesaikan tulisan saya sendiri. Proyek (setengah) selesai mungkin akan menambah kuburan pembuat kode di github - jika ada yang ingin melanjutkan proyek - jangan ragu untuk menulis.








All Articles