Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/tcpdf/barcodes.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
5
Modification information for LGPL compliance
6
7
r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
8
9
r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
10
11
r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
12
13
r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3  tags and updated the build system 
14
15
r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
16
17
r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
18
19
r46451 - 2009-04-23 16:57:40 -0700 (Thu, 23 Apr 2009) - jenny - tcpdf initial checkin.
20
21
22
*/
23
24
25
//============================================================+
26
// File name   : barcodes.php
27
// Begin       : 2008-06-09
28
// Last Update : 2009-04-15
29
// Version     : 1.0.008
30
// License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
31
// 	----------------------------------------------------------------------------
32
//  Copyright (C) 2008-2009 Nicola Asuni - Tecnick.com S.r.l.
33
// 	
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
34
// 	This program is free software: you can redistribute it and/or modify
35
// 	it under the terms of the GNU Lesser General Public License as published by
36
// 	the Free Software Foundation, either version 2.1 of the License, or
37
// 	(at your option) any later version.
38
// 	
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
39
// 	This program is distributed in the hope that it will be useful,
40
// 	but WITHOUT ANY WARRANTY; without even the implied warranty of
41
// 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
// 	GNU Lesser General Public License for more details.
43
// 	
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
44
// 	You should have received a copy of the GNU Lesser General Public License
45
// 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
46
// 	
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
47
// 	See LICENSE.TXT file for more information.
48
//  ----------------------------------------------------------------------------
49
//
50
// Description : PHP class to creates array representations for 
51
//               common 1D barcodes to be used with TCPDF.
52
//
53
// Author: Nicola Asuni
54
//
55
// (c) Copyright:
56
//               Nicola Asuni
57
//               Tecnick.com S.r.l.
58
//               Via della Pace, 11
59
//               09044 Quartucciu (CA)
60
//               ITALY
61
//               www.tecnick.com
62
//               [email protected]
63
//============================================================+
64
65
/**
66
 * PHP class to creates array representations for common 1D barcodes to be used with TCPDF.
67
 * @package com.tecnick.tcpdf
68
 * @abstract Functions for generating string representation of common 1D barcodes.
69
 * @author Nicola Asuni
70
 * @copyright 2008-2009 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - [email protected]
71
 * @link http://www.tcpdf.org
72
 * @license http://www.gnu.org/copyleft/lesser.html LGPL
73
 * @version 1.0.008
74
 */
75
76
	/**
77
	* PHP class to creates array representations for common 1D barcodes to be used with TCPDF (http://www.tcpdf.org).<br>
78
	* @name TCPDFBarcode
79
	* @package com.tecnick.tcpdf
80
	* @version 1.0.008
81
	* @author Nicola Asuni
82
	* @link http://www.tcpdf.org
83
	* @license http://www.gnu.org/copyleft/lesser.html LGPL
84
	*/
85
class TCPDFBarcode {
86
	
87
	/**
88
	 * @var array representation of barcode.
89
	 * @access protected
90
	 */
91
	protected $barcode_array;
92
		
93
	/**
94
	 * This is the class constructor. 
95
	 * Return an array representations for common 1D barcodes:<ul>
96
	 * <li>$arrcode['code'] code to be printed on text label</li>
97
	 * <li>$arrcode['maxh'] max bar height</li>
98
	 * <li>$arrcode['maxw'] max bar width</li>
99
	 * <li>$arrcode['bcode'][$k] single bar or space in $k position</li>
100
	 * <li>$arrcode['bcode'][$k]['t'] bar type: true = bar, false = space.</li>
101
	 * <li>$arrcode['bcode'][$k]['w'] bar width in units.</li>
102
	 * <li>$arrcode['bcode'][$k]['h'] bar height in units.</li>
103
	 * <li>$arrcode['bcode'][$k]['p'] bar top position (0 = top, 1 = middle)</li></ul>
104
	 * @param string $code code to print
105
 	 * @param string $type type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extention</li><li>EAN5 : 5-Digits UPC-Based Extention</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
106
	 */
107
	public function __construct($code, $type) {
108
		$this->setBarcode($code, $type);
109
	}
110
	
111
	/** 
112
	 * Return an array representations of barcode.
113
 	 * @return array
114
	 */
115
	public function getBarcodeArray() {
116
		return $this->barcode_array;
117
	}
118
	
119
	/** 
120
	 * Set the barcode.
121
	 * @param string $code code to print
122
 	 * @param string $type type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extention</li><li>EAN5 : 5-Digits UPC-Based Extention</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
123
 	 * @return array
124
	 */
125
	public function setBarcode($code, $type) {
126
		switch (strtoupper($type)) {
127
			case 'C39': { // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
128
				$arrcode = $this->barcode_code39($code, false, false);
129
				break;
130
			}
131
			case 'C39+': { // CODE 39 with checksum
132
				$arrcode = $this->barcode_code39($code, false, true);
133
				break;
134
			}
135
			case 'C39E': { // CODE 39 EXTENDED
136
				$arrcode = $this->barcode_code39($code, true, false);
137
				break;
138
			}
139
			case 'C39E+': { // CODE 39 EXTENDED + CHECKSUM
140
				$arrcode = $this->barcode_code39($code, true, true);
141
				break;
142
			}
143
			case 'C93': { // CODE 93 - USS-93
144
				$arrcode = $this->barcode_code93($code);
145
				break;
146
			}
147
			case 'S25': { // Standard 2 of 5
148
				$arrcode = $this->barcode_s25($code, false);
149
				break;
150
			}
151
			case 'S25+': { // Standard 2 of 5 + CHECKSUM
152
				$arrcode = $this->barcode_s25($code, true);
153
				break;
154
			}
155
			case 'I25': { // Interleaved 2 of 5
156
				$arrcode = $this->barcode_i25($code, false);
157
				break;
158
			}
159
			case 'I25+': { // Interleaved 2 of 5 + CHECKSUM
160
				$arrcode = $this->barcode_i25($code, true);
161
				break;
162
			}
163
			case 'C128A': { // CODE 128 A
164
				$arrcode = $this->barcode_c128($code, 'A');
165
				break;
166
			}
167
			case 'C128B': { // CODE 128 B
168
				$arrcode = $this->barcode_c128($code, 'B');
169
				break;
170
			}
171
			case 'C128C': { // CODE 128 C
172
				$arrcode = $this->barcode_c128($code, 'C');
173
				break;
174
			}
175
			case 'EAN2': { // 2-Digits UPC-Based Extention
176
				$arrcode = $this->barcode_eanext($code, 2);
177
				break;
178
			}
179
			case 'EAN5': { // 5-Digits UPC-Based Extention
180
				$arrcode = $this->barcode_eanext($code, 5);
181
				break;
182
			}
183
			case 'EAN8': { // EAN 8
184
				$arrcode = $this->barcode_eanupc($code, 8);
185
				break;
186
			}
187
			case 'EAN13': { // EAN 13
188
				$arrcode = $this->barcode_eanupc($code, 13);
189
				break;
190
			}
191
			case 'UPCA': { // UPC-A
192
				$arrcode = $this->barcode_eanupc($code, 12);
193
				break;
194
			}
195
			case 'UPCE': { // UPC-E
196
				$arrcode = $this->barcode_eanupc($code, 6);
197
				break;
198
			}
199
			case 'MSI': { // MSI (Variation of Plessey code)
200
				$arrcode = $this->barcode_msi($code, false);
201
				break;
202
			}
203
			case 'MSI+': { // MSI + CHECKSUM (modulo 11)
204
				$arrcode = $this->barcode_msi($code, true);
205
				break;
206
			}
207
			case 'POSTNET': { // POSTNET
208
				$arrcode = $this->barcode_postnet($code, false);
209
				break;
210
			}
211
			case 'PLANET': { // PLANET
212
				$arrcode = $this->barcode_postnet($code, true);
213
				break;
214
			}
215
			case 'RMS4CC': { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
216
				$arrcode = $this->barcode_rms4cc($code, false);
217
				break;
218
			}
219
			case 'KIX': { // KIX (Klant index - Customer index)
220
				$arrcode = $this->barcode_rms4cc($code, true);
221
				break;
222
			}
223
			case 'IMB': { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
224
				$arrcode = $this->barcode_imb($code);
225
				break;
226
			}
227
			case 'CODABAR': { // CODABAR
228
				$arrcode = $this->barcode_codabar($code);
229
				break;
230
			}
231
			case 'CODE11': { // CODE 11
232
				$arrcode = $this->barcode_code11($code);
233
				break;
234
			}
235
			case 'PHARMA': { // PHARMACODE
236
				$arrcode = $this->barcode_pharmacode($code);
237
				break;
238
			}
239
			case 'PHARMA2T': { // PHARMACODE TWO-TRACKS
240
				$arrcode = $this->barcode_pharmacode2t($code);
241
				break;
242
			}
243
			default: {
0 ignored issues
show
DEFAULT statements must be defined using a colon

As per the PSR-2 coding standard, default statements should not be wrapped in curly braces.

switch ($expr) {
    default: { //wrong
        doSomething();
        break;
    }
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
244
				$this->barcode_array = false;
245
			}
246
		}
247
		$this->barcode_array = $arrcode;
248
	}
249
	
250
	/**
251
	 * CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
252
	 * General-purpose code in very wide use world-wide
253
	 * @param string $code code to represent.
254
	 * @param boolean $checksum if true add a checksum to the code
255
	 * @return array barcode representation.
256
	 * @access protected
257
	 */
258
	protected function barcode_code39($code, $extended=false, $checksum=false) {
259
		$chr['0'] = '111221211';
260
		$chr['1'] = '211211112';
261
		$chr['2'] = '112211112';
262
		$chr['3'] = '212211111';
263
		$chr['4'] = '111221112';
264
		$chr['5'] = '211221111';
265
		$chr['6'] = '112221111';
266
		$chr['7'] = '111211212';
267
		$chr['8'] = '211211211';
268
		$chr['9'] = '112211211';
269
		$chr['A'] = '211112112';
270
		$chr['B'] = '112112112';
271
		$chr['C'] = '212112111';
272
		$chr['D'] = '111122112';
273
		$chr['E'] = '211122111';
274
		$chr['F'] = '112122111';
275
		$chr['G'] = '111112212';
276
		$chr['H'] = '211112211';
277
		$chr['I'] = '112112211';
278
		$chr['J'] = '111122211';
279
		$chr['K'] = '211111122';
280
		$chr['L'] = '112111122';
281
		$chr['M'] = '212111121';
282
		$chr['N'] = '111121122';
283
		$chr['O'] = '211121121';
284
		$chr['P'] = '112121121';
285
		$chr['Q'] = '111111222';
286
		$chr['R'] = '211111221';
287
		$chr['S'] = '112111221';
288
		$chr['T'] = '111121221';
289
		$chr['U'] = '221111112';
290
		$chr['V'] = '122111112';
291
		$chr['W'] = '222111111';
292
		$chr['X'] = '121121112';
293
		$chr['Y'] = '221121111';
294
		$chr['Z'] = '122121111';
295
		$chr['-'] = '121111212';
296
		$chr['.'] = '221111211';
297
		$chr[' '] = '122111211';
298
		$chr['$'] = '121212111';
299
		$chr['/'] = '121211121';
300
		$chr['+'] = '121112121';
301
		$chr['%'] = '111212121';
302
		$chr['*'] = '121121211';
303
		
304
		$code = strtoupper($code);
305
		if ($extended) {
306
			// extended mode
307
			$code = $this->encode_code39_ext($code);
308
		}
309
		if ($code === false) {
310
			return false;
311
		}
312
		if ($checksum) {
313
			// checksum
314
			$code .= $this->checksum_code39($code);
315
		}
316
		// add start and stop codes
317
		$code = '*'.$code.'*';
318
		
319
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
320
		$k = 0;
321
		$clen = strlen($code);
322
		for ($i = 0; $i < $clen; ++$i) {
323
			$char = $code{$i};
324
			if(!isset($chr[$char])) {
325
				// invalid character
326
				return false;
327
			}
328
			for ($j = 0; $j < 9; ++$j) {
329
				if (($j % 2) == 0) {
330
					$t = true; // bar
331
				} else {
332
					$t = false; // space
333
				}
334
				$w = $chr[$char]{$j};
335
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
336
				$bararray['maxw'] += $w;
337
				++$k;
338
			}
339
			$bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0);
340
			$bararray['maxw'] += 1;
341
			++$k;
342
		}
343
		return $bararray;
344
	}
345
	
346
	/**
347
	 * Encode a string to be used for CODE 39 Extended mode.
348
	 * @param string $code code to represent.
349
	 * @return encoded string.
350
	 * @access protected
351
	 */
352
	protected function encode_code39_ext($code) {
353
		$encode = array(
354
			chr(0) => '%U', chr(1) => '$A', chr(2) => '$B', chr(3) => '$C',
355
			chr(4) => '$D', chr(5) => '$E', chr(6) => '$F', chr(7) => '$G',
356
			chr(8) => '$H', chr(9) => '$I', chr(10) => '$J', chr(11) => '£K',
357
			chr(12) => '$L', chr(13) => '$M', chr(14) => '$N', chr(15) => '$O',
358
			chr(16) => '$P', chr(17) => '$Q', chr(18) => '$R', chr(19) => '$S',
359
			chr(20) => '$T', chr(21) => '$U', chr(22) => '$V', chr(23) => '$W',
360
			chr(24) => '$X', chr(25) => '$Y', chr(26) => '$Z', chr(27) => '%A',
361
			chr(28) => '%B', chr(29) => '%C', chr(30) => '%D', chr(31) => '%E',
362
			chr(32) => ' ', chr(33) => '/A', chr(34) => '/B', chr(35) => '/C',
363
			chr(36) => '/D', chr(37) => '/E', chr(38) => '/F', chr(39) => '/G',
364
			chr(40) => '/H', chr(41) => '/I', chr(42) => '/J', chr(43) => '/K',
365
			chr(44) => '/L', chr(45) => '-', chr(46) => '.', chr(47) => '/O',
366
			chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
367
			chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
368
			chr(56) => '8', chr(57) => '9', chr(58) => '/Z', chr(59) => '%F',
369
			chr(60) => '%G', chr(61) => '%H', chr(62) => '%I', chr(63) => '%J',
370
			chr(64) => '%V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
371
			chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
372
			chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
373
			chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
374
			chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
375
			chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
376
			chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => '%K',
377
			chr(92) => '%L', chr(93) => '%M', chr(94) => '%N', chr(95) => '%O',
378
			chr(96) => '%W', chr(97) => '+A', chr(98) => '+B', chr(99) => '+C',
379
			chr(100) => '+D', chr(101) => '+E', chr(102) => '+F', chr(103) => '+G',
380
			chr(104) => '+H', chr(105) => '+I', chr(106) => '+J', chr(107) => '+K',
381
			chr(108) => '+L', chr(109) => '+M', chr(110) => '+N', chr(111) => '+O',
382
			chr(112) => '+P', chr(113) => '+Q', chr(114) => '+R', chr(115) => '+S',
383
			chr(116) => '+T', chr(117) => '+U', chr(118) => '+V', chr(119) => '+W',
384
			chr(120) => '+X', chr(121) => '+Y', chr(122) => '+Z', chr(123) => '%P',
385
			chr(124) => '%Q', chr(125) => '%R', chr(126) => '%S', chr(127) => '%T');
386
		$code_ext = '';
387
		$clen = strlen($code);
388
		for ($i = 0 ; $i < $clen; ++$i) {
389
			if (ord($code{$i}) > 127) {
390
				return false;
391
			}
392
			$code_ext .= $encode[$code{$i}];
393
		}
394
		return $code_ext;
395
	}
396
	
397
	/**
398
	 * Calculate CODE 39 checksum (modulo 43).
399
	 * @param string $code code to represent.
400
	 * @return char checksum.
401
	 * @access protected
402
	 */
403
	protected function checksum_code39($code) {
404
		$chars = array(
405
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
406
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
407
			'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
408
			'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%');
409
		$sum = 0;
410
		$clen = strlen($code);
411
		for ($i = 0 ; $i < $clen; ++$i) {
412
			$k = array_keys($chars, $code{$i});
413
			$sum += $k[0];
414
		}
415
		$j = ($sum % 43);
416
		return $chars[$j];
417
	}
418
	
419
	/**
420
	 * CODE 93 - USS-93
421
	 * Compact code similar to Code 39
422
	 * @param string $code code to represent.
423
	 * @param boolean $checksum if true add a checksum to the code
0 ignored issues
show
There is no parameter named $checksum. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
424
	 * @return array barcode representation.
425
	 * @access protected
426
	 */
427
	protected function barcode_code93($code) {
428
		$chr['0'] = '131112';
429
		$chr['1'] = '111213';
430
		$chr['2'] = '111312';
431
		$chr['3'] = '111411';
432
		$chr['4'] = '121113';
433
		$chr['5'] = '121212';
434
		$chr['6'] = '121311';
435
		$chr['7'] = '111114';
436
		$chr['8'] = '131211';
437
		$chr['9'] = '141111';
438
		$chr['A'] = '211113';
439
		$chr['B'] = '211212';
440
		$chr['C'] = '211311';
441
		$chr['D'] = '221112';
442
		$chr['E'] = '221211';
443
		$chr['F'] = '231111';
444
		$chr['G'] = '112113';
445
		$chr['H'] = '112212';
446
		$chr['I'] = '112311';
447
		$chr['J'] = '122112';
448
		$chr['K'] = '132111';
449
		$chr['L'] = '111123';
450
		$chr['M'] = '111222';
451
		$chr['N'] = '111321';
452
		$chr['O'] = '121122';
453
		$chr['P'] = '131121';
454
		$chr['Q'] = '212112';
455
		$chr['R'] = '212211';
456
		$chr['S'] = '211122';
457
		$chr['T'] = '211221';
458
		$chr['U'] = '221121';
459
		$chr['V'] = '222111';
460
		$chr['W'] = '112122';
461
		$chr['X'] = '112221';
462
		$chr['Y'] = '122121';
463
		$chr['Z'] = '123111';
464
		$chr['-'] = '121131';
465
		$chr['.'] = '311112';
466
		$chr[' '] = '311211';
467
		$chr['$'] = '321111';
468
		$chr['/'] = '112131';
469
		$chr['+'] = '113121';
470
		$chr['%'] = '211131';
471
		$chr[128] = '121221'; // ($)
472
		$chr[129] = '311121'; // (/)
473
		$chr[130] = '122211'; // (+)
474
		$chr[131] = '312111'; // (%)
475
		$chr['*'] = '111141';
476
		$code = strtoupper($code);
477
		$encode = array(
478
			chr(0) => chr(131).'U', chr(1) => chr(128).'A', chr(2) => chr(128).'B', chr(3) => chr(128).'C',
479
			chr(4) => chr(128).'D', chr(5) => chr(128).'E', chr(6) => chr(128).'F', chr(7) => chr(128).'G',
480
			chr(8) => chr(128).'H', chr(9) => chr(128).'I', chr(10) => chr(128).'J', chr(11) => '£K',
481
			chr(12) => chr(128).'L', chr(13) => chr(128).'M', chr(14) => chr(128).'N', chr(15) => chr(128).'O',
482
			chr(16) => chr(128).'P', chr(17) => chr(128).'Q', chr(18) => chr(128).'R', chr(19) => chr(128).'S',
483
			chr(20) => chr(128).'T', chr(21) => chr(128).'U', chr(22) => chr(128).'V', chr(23) => chr(128).'W',
484
			chr(24) => chr(128).'X', chr(25) => chr(128).'Y', chr(26) => chr(128).'Z', chr(27) => chr(131).'A',
485
			chr(28) => chr(131).'B', chr(29) => chr(131).'C', chr(30) => chr(131).'D', chr(31) => chr(131).'E',
486
			chr(32) => ' ', chr(33) => chr(129).'A', chr(34) => chr(129).'B', chr(35) => chr(129).'C',
487
			chr(36) => chr(129).'D', chr(37) => chr(129).'E', chr(38) => chr(129).'F', chr(39) => chr(129).'G',
488
			chr(40) => chr(129).'H', chr(41) => chr(129).'I', chr(42) => chr(129).'J', chr(43) => chr(129).'K',
489
			chr(44) => chr(129).'L', chr(45) => '-', chr(46) => '.', chr(47) => chr(129).'O',
490
			chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
491
			chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
492
			chr(56) => '8', chr(57) => '9', chr(58) => chr(129).'Z', chr(59) => chr(131).'F',
493
			chr(60) => chr(131).'G', chr(61) => chr(131).'H', chr(62) => chr(131).'I', chr(63) => chr(131).'J',
494
			chr(64) => chr(131).'V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
495
			chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
496
			chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
497
			chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
498
			chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
499
			chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
500
			chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => chr(131).'K',
501
			chr(92) => chr(131).'L', chr(93) => chr(131).'M', chr(94) => chr(131).'N', chr(95) => chr(131).'O',
502
			chr(96) => chr(131).'W', chr(97) => chr(130).'A', chr(98) => chr(130).'B', chr(99) => chr(130).'C',
503
			chr(100) => chr(130).'D', chr(101) => chr(130).'E', chr(102) => chr(130).'F', chr(103) => chr(130).'G',
504
			chr(104) => chr(130).'H', chr(105) => chr(130).'I', chr(106) => chr(130).'J', chr(107) => chr(130).'K',
505
			chr(108) => chr(130).'L', chr(109) => chr(130).'M', chr(110) => chr(130).'N', chr(111) => chr(130).'O',
506
			chr(112) => chr(130).'P', chr(113) => chr(130).'Q', chr(114) => chr(130).'R', chr(115) => chr(130).'S',
507
			chr(116) => chr(130).'T', chr(117) => chr(130).'U', chr(118) => chr(130).'V', chr(119) => chr(130).'W',
508
			chr(120) => chr(130).'X', chr(121) => chr(130).'Y', chr(122) => chr(130).'Z', chr(123) => chr(131).'P',
509
			chr(124) => chr(131).'Q', chr(125) => chr(131).'R', chr(126) => chr(131).'S', chr(127) => chr(131).'T');
510
		$code_ext = '';
511
		$clen = strlen($code);
512
		for ($i = 0 ; $i < $clen; ++$i) {
513
			if (ord($code{$i}) > 127) {
514
				return false;
515
			}
516
			$code_ext .= $encode[$code{$i}];
517
		}
518
		// checksum
519
		$code .= $this->checksum_code93($code);
520
		// add start and stop codes
521
		$code = '*'.$code.'*';
522
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
523
		$k = 0;
524
		$clen = strlen($code);
525
		for ($i = 0; $i < $clen; ++$i) {
526
			$char = $code{$i};
527
			if(!isset($chr[$char])) {
528
				// invalid character
529
				return false;
530
			}
531
			for ($j = 0; $j < 6; ++$j) {
532
				if (($j % 2) == 0) {
533
					$t = true; // bar
534
				} else {
535
					$t = false; // space
536
				}
537
				$w = $chr[$char]{$j};
538
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
539
				$bararray['maxw'] += $w;
540
				++$k;
541
			}
542
		}
543
		$bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0);
544
		$bararray['maxw'] += 1;
545
		++$k;		
546
		return $bararray;
547
	}
548
	
549
	/**
550
	 * Calculate CODE 93 checksum (modulo 47).
551
	 * @param string $code code to represent.
552
	 * @return string checksum code.
553
	 * @access protected
554
	 */
555
	protected function checksum_code93($code) {
556
		$chars = array(
557
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
558
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
559
			'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
560
			'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%');
561
		// translate special characters
562
		$code = strtr($code, chr(128).chr(129).chr(130).chr(131), '$/+%');	
563
		$len = strlen($code);
564
		// calculate check digit C
565
		$p = 1;
566
		$check = 0;
567
		for ($i = ($len - 1); $i >= 0; --$i) {
568
			$k = array_keys($chars, $code{$i});
569
			$check += ($k[0] * $p);
570
			++$p;
571
			if ($p > 20) {
572
				$p = 1;
573
			}
574
		}
575
		$check %= 47;
576
		$c = $chars[$check];
577
		$code .= $c;
578
		// calculate check digit K
579
		$p = 1;
580
		$check = 0;
581
		for ($i = $len; $i >= 0; --$i) {
582
			$k = array_keys($chars, $code{$i});
583
			$check += ($k[0] * $p);
584
			++$p;
585
			if ($p > 15) {
586
				$p = 1;
587
			}
588
		}
589
		$check %= 47;
590
		$k = $chars[$check];
591
		return $c.$k;
592
	}
593
	
594
	/**
595
	 * Checksum for standard 2 of 5 barcodes.
596
	 * @param string $code code to process.
597
	 * @return int checksum.
598
	 * @access protected
599
	 */
600
	protected function checksum_s25($code) {
601
		$len = strlen($code);
602
		$sum = 0;
603
		for ($i = 0; $i < $len; $i+=2) {
604
			$sum += $code{$i};
605
		}
606
		$sum *= 3;
607
		for ($i = 1; $i < $len; $i+=2) {
608
			$sum += ($code{$i});
609
		}
610
		$r = $sum % 10;
611
		if($r > 0) {
612
			$r = (10 - $r);
613
		}
614
		return $r;
615
	}
616
	
617
	/**
618
	 * MSI.
619
	 * Variation of Plessey code, with similar applications 
620
	 * Contains digits (0 to 9) and encodes the data only in the width of bars.
621
	 * @param string $code code to represent.
622
	 * @param boolean $checksum if true add a checksum to the code (modulo 11)
623
	 * @return array barcode representation.
624
	 * @access protected
625
	 */
626
	protected function barcode_msi($code, $checksum=false) {
627
		$chr['0'] = '100100100100';
628
		$chr['1'] = '100100100110';
629
		$chr['2'] = '100100110100';
630
		$chr['3'] = '100100110110';
631
		$chr['4'] = '100110100100';
632
		$chr['5'] = '100110100110';
633
		$chr['6'] = '100110110100';
634
		$chr['7'] = '100110110110';
635
		$chr['8'] = '110100100100';
636
		$chr['9'] = '110100100110';
637
		$chr['A'] = '110100110100';
638
		$chr['B'] = '110100110110';
639
		$chr['C'] = '110110100100';
640
		$chr['D'] = '110110100110';
641
		$chr['E'] = '110110110100';
642
		$chr['F'] = '110110110110';
643
		if ($checksum) {
644
			// add checksum
645
			$clen = strlen($code);
646
			$p = 2;
647
			$check = 0;
648
			for ($i = ($clen - 1); $i >= 0; --$i) {
649
				$check += (hexdec($code{$i}) * $p);
650
				++$p;
651
				if ($p > 7) {
652
					$p = 2;
653
				}
654
			}
655
			$check %= 11;
656
			if ($check > 0) {
657
				$check = 11 - $check;
658
			}
659
			$code .= $check;
660
		}
661
		$seq = '110'; // left guard
662
		$clen = strlen($code);
663
		for ($i = 0; $i < $clen; ++$i) {
664
			$digit = $code{$i};
665
			if (!isset($chr[$digit])) {
666
				// invalid character
667
				return false;
668
			}
669
			$seq .= $chr[$digit];
670
		}		
671
		$seq .= '1001'; // right guard
672
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
673
		return $this->binseq_to_array($seq, $bararray);
674
	}
675
	
676
	/**
677
	 * Standard 2 of 5 barcodes.
678
	 * Used in airline ticket marking, photofinishing
679
	 * Contains digits (0 to 9) and encodes the data only in the width of bars.
680
	 * @param string $code code to represent.
681
	 * @param boolean $checksum if true add a checksum to the code
682
	 * @return array barcode representation.
683
	 * @access protected
684
	 */
685
	protected function barcode_s25($code, $checksum=false) {
686
		$chr['0'] = '10101110111010';
687
		$chr['1'] = '11101010101110';
688
		$chr['2'] = '10111010101110';
689
		$chr['3'] = '11101110101010';
690
		$chr['4'] = '10101110101110';
691
		$chr['5'] = '11101011101010';
692
		$chr['6'] = '10111011101010';
693
		$chr['7'] = '10101011101110';
694
		$chr['8'] = '10101110111010';
695
		$chr['9'] = '10111010111010';
696
		if ($checksum) {
697
			// add checksum
698
			$code .= $this->checksum_s25($code);
699
		}
700
		if((strlen($code) % 2) != 0) {
701
			// add leading zero if code-length is odd
702
			$code = '0'.$code;
703
		}
704
		$seq = '11011010';
705
		$clen = strlen($code);
706
		for ($i = 0; $i < $clen; ++$i) {
707
			$digit = $code{$i};
708
			if (!isset($chr[$digit])) {
709
				// invalid character
710
				return false;
711
			}
712
			$seq .= $chr[$digit];
713
		}		
714
		$seq .= '1101011';
715
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
716
		return $this->binseq_to_array($seq, $bararray);
717
	}
718
	
719
	/**
720
	 * Convert binary barcode sequence to TCPDF barcode array
721
	 * @param string $seq barcode as binary sequence
722
	 * òparam array $bararray TCPDF barcode array to fill up
723
	 * @return array barcode representation.
724
	 * @access protected
725
	 */
726
	protected function binseq_to_array($seq, $bararray) {
727
		$len = strlen($seq);
728
		$w = 0;
729
		$k = 0;
730
		for ($i = 0; $i < $len; ++$i) {
731
			$w += 1;
732
			if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq{$i} != $seq{($i+1)}))) {
733
				if ($seq{$i} == '1') {
734
					$t = true; // bar
735
				} else {
736
					$t = false; // space
737
				}
738
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
739
				$bararray['maxw'] += $w;
740
				++$k;
741
				$w = 0;
742
			}
743
		}
744
		return $bararray;
745
	}
746
	
747
	/**
748
	 * Interleaved 2 of 5 barcodes.
749
	 * Compact numeric code, widely used in industry, air cargo
750
	 * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces.
751
	 * @param string $code code to represent.
752
	 * @param boolean $checksum if true add a checksum to the code
753
	 * @return array barcode representation.
754
	 * @access protected
755
	 */
756
	protected function barcode_i25($code, $checksum=false) {
757
		$chr['0'] = '11221';
758
		$chr['1'] = '21112';
759
		$chr['2'] = '12112';
760
		$chr['3'] = '22111';
761
		$chr['4'] = '11212';
762
		$chr['5'] = '21211';
763
		$chr['6'] = '12211';
764
		$chr['7'] = '11122';
765
		$chr['8'] = '21121';
766
		$chr['9'] = '12121';
767
		$chr['A'] = '11';
768
		$chr['Z'] = '21';
769
		if ($checksum) {
770
			// add checksum
771
			$code .= $this->checksum_s25($code);
772
		}
773
		if((strlen($code) % 2) != 0) {
774
			// add leading zero if code-length is odd
775
			$code = '0'.$code;
776
		}
777
		// add start and stop codes
778
		$code = 'AA'.strtolower($code).'ZA';
779
			
780
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
781
		$k = 0;
782
		$clen = strlen($code);
783
		for ($i = 0; $i < $clen; $i = ($i + 2)) {
784
			$char_bar = $code{$i};
785
			$char_space = $code{$i+1};
786
			if((!isset($chr[$char_bar])) OR (!isset($chr[$char_space]))) {
787
				// invalid character
788
				return false;
789
			}
790
			// create a bar-space sequence
791
			$seq = '';
792
			$chrlen = strlen($chr[$char_bar]);
793
			for ($s = 0; $s < $chrlen; $s++){
794
				$seq .= $chr[$char_bar]{$s} . $chr[$char_space]{$s};
795
			}
796
			$seqlen = strlen($seq);
797
			for ($j = 0; $j < $seqlen; ++$j) {
798
				if (($j % 2) == 0) {
799
					$t = true; // bar
800
				} else {
801
					$t = false; // space
802
				}
803
				$w = $seq{$j};
804
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
805
				$bararray['maxw'] += $w;
806
				++$k;
807
			}
808
		}
809
		return $bararray;
810
	}
811
	
812
	/**
813
	 * C128 barcodes. 
814
	 * Very capable code, excellent density, high reliability; in very wide use world-wide
815
	 * @param string $code code to represent.
816
	 * @param string $type barcode type: A, B or C
817
	 * @return array barcode representation.
818
	 * @access protected
819
	 */
820
	protected function barcode_c128($code, $type='B') {
821
		$chr = array(
822
			'212222', /* 00 */
823
			'222122', /* 01 */
824
			'222221', /* 02 */
825
			'121223', /* 03 */
826
			'121322', /* 04 */
827
			'131222', /* 05 */
828
			'122213', /* 06 */
829
			'122312', /* 07 */
830
			'132212', /* 08 */
831
			'221213', /* 09 */
832
			'221312', /* 10 */
833
			'231212', /* 11 */
834
			'112232', /* 12 */
835
			'122132', /* 13 */
836
			'122231', /* 14 */
837
			'113222', /* 15 */
838
			'123122', /* 16 */
839
			'123221', /* 17 */
840
			'223211', /* 18 */
841
			'221132', /* 19 */
842
			'221231', /* 20 */
843
			'213212', /* 21 */
844
			'223112', /* 22 */
845
			'312131', /* 23 */
846
			'311222', /* 24 */
847
			'321122', /* 25 */
848
			'321221', /* 26 */
849
			'312212', /* 27 */
850
			'322112', /* 28 */
851
			'322211', /* 29 */
852
			'212123', /* 30 */
853
			'212321', /* 31 */
854
			'232121', /* 32 */
855
			'111323', /* 33 */
856
			'131123', /* 34 */
857
			'131321', /* 35 */
858
			'112313', /* 36 */
859
			'132113', /* 37 */
860
			'132311', /* 38 */
861
			'211313', /* 39 */
862
			'231113', /* 40 */
863
			'231311', /* 41 */
864
			'112133', /* 42 */
865
			'112331', /* 43 */
866
			'132131', /* 44 */
867
			'113123', /* 45 */
868
			'113321', /* 46 */
869
			'133121', /* 47 */
870
			'313121', /* 48 */
871
			'211331', /* 49 */
872
			'231131', /* 50 */
873
			'213113', /* 51 */
874
			'213311', /* 52 */
875
			'213131', /* 53 */
876
			'311123', /* 54 */
877
			'311321', /* 55 */
878
			'331121', /* 56 */
879
			'312113', /* 57 */
880
			'312311', /* 58 */
881
			'332111', /* 59 */
882
			'314111', /* 60 */
883
			'221411', /* 61 */
884
			'431111', /* 62 */
885
			'111224', /* 63 */
886
			'111422', /* 64 */
887
			'121124', /* 65 */
888
			'121421', /* 66 */
889
			'141122', /* 67 */
890
			'141221', /* 68 */
891
			'112214', /* 69 */
892
			'112412', /* 70 */
893
			'122114', /* 71 */
894
			'122411', /* 72 */
895
			'142112', /* 73 */
896
			'142211', /* 74 */
897
			'241211', /* 75 */
898
			'221114', /* 76 */
899
			'413111', /* 77 */
900
			'241112', /* 78 */
901
			'134111', /* 79 */
902
			'111242', /* 80 */
903
			'121142', /* 81 */
904
			'121241', /* 82 */
905
			'114212', /* 83 */
906
			'124112', /* 84 */
907
			'124211', /* 85 */
908
			'411212', /* 86 */
909
			'421112', /* 87 */
910
			'421211', /* 88 */
911
			'212141', /* 89 */
912
			'214121', /* 90 */
913
			'412121', /* 91 */
914
			'111143', /* 92 */
915
			'111341', /* 93 */
916
			'131141', /* 94 */
917
			'114113', /* 95 */
918
			'114311', /* 96 */
919
			'411113', /* 97 */
920
			'411311', /* 98 */
921
			'113141', /* 99 */
922
			'114131', /* 100 */
923
			'311141', /* 101 */
924
			'411131', /* 102 */
925
			'211412', /* 103 START A */
926
			'211214', /* 104 START B  */
927
			'211232', /* 105 START C  */
928
			'233111', /* STOP */
929
			'200000'  /* END */
930
		);
931
		$keys = '';
932
		switch(strtoupper($type)) {
933
			case 'A': {
934
				$startid = 103;
935
				$keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
936
				for ($i = 0; $i < 32; ++$i) {
937
					$keys .= chr($i);
938
				}
939
				break;
940
			}
941
			case 'B': {
942
				$startid = 104;
943
				$keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'.chr(127);
944
				break;
945
			}
946
			case 'C': {
947
				$startid = 105;
948
				$keys = '';
949
				if ((strlen($code) % 2) != 0) {
950
					// The length of barcode value must be even ($code). You must pad the number with zeros
951
					return false;
952
				}
953
				for ($i = 0; $i <= 99; ++$i) {
954
					$keys .= chr($i);
955
				}
956
				$new_code = '';
957
				$hclen = (strlen($code) / 2);
958
				for ($i = 0; $i < $hclen; ++$i) {
959
					$new_code .= chr(intval($code{(2 * $i)}.$code{(2 * $i + 1)}));
960
				}
961
				$code = $new_code;
962
				break;
963
			}
964
			default: {
0 ignored issues
show
DEFAULT statements must be defined using a colon

As per the PSR-2 coding standard, default statements should not be wrapped in curly braces.

switch ($expr) {
    default: { //wrong
        doSomething();
        break;
    }
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
965
				return false;
966
			}
967
		}
968
		// calculate check character
969
		$sum = $startid;
970
		$clen = strlen($code);
971
		for ($i = 0; $i < $clen; ++$i) {
972
			$sum +=  (strpos($keys, $code{$i}) * ($i+1));
973
		}
974
		$check = ($sum % 103);
975
		// add start, check and stop codes
976
		$code = chr($startid).$code.chr($check).chr(106).chr(107);
977
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
978
		$k = 0;
979
		$len = strlen($code);
980
		for ($i = 0; $i < $len; ++$i) {
981
			$ck = strpos($keys, $code{$i});
982
			if (($i == 0) OR ($i > ($len-4))) {
983
				$char_num = ord($code{$i});
984
				$seq = $chr[$char_num];
985
			} elseif(($ck >= 0) AND isset($chr[$ck])) {
986
					$seq = $chr[$ck];
987
			} else {
988
				// invalid character
989
				return false;
990
			}
991
			for ($j = 0; $j < 6; ++$j) {
992
				if (($j % 2) == 0) {
993
					$t = true; // bar
994
				} else {
995
					$t = false; // space
996
				}
997
				$w = $seq{$j};
998
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
999
				$bararray['maxw'] += $w;
1000
				++$k;
1001
			}
1002
		}
1003
		return $bararray;		
1004
	}
1005
	
1006
	/**
1007
	 * EAN13 and UPC-A barcodes.
1008
	 * EAN13: European Article Numbering international retail product code
1009
	 * UPC-A: Universal product code seen on almost all retail products in the USA and Canada
1010
	 * UPC-E: Short version of UPC symbol
1011
	 * @param string $code code to represent.
1012
	 * @param string $len barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A
1013
	 * @return array barcode representation.
1014
	 * @access protected
1015
	 */
1016
	protected function barcode_eanupc($code, $len=13) {
1017
		$upce = false;
1018
		if ($len == 6) {
1019
			$len = 12; // UPC-A
1020
			$upce = true; // UPC-E mode
1021
		}
1022
		$data_len = $len - 1;
1023
		//Padding
1024
		$code = str_pad($code, $data_len, '0', STR_PAD_LEFT);
1025
		$code_len = strlen($code);
1026
		// calculate check digit
1027
		$sum_a = 0;
1028
		for ($i = 1; $i < $data_len; $i+=2) {
1029
			$sum_a += $code{$i};
1030
		}
1031
		if ($len > 12) {
1032
			$sum_a *= 3;
1033
		}
1034
		$sum_b = 0;
1035
		for ($i = 0; $i < $data_len; $i+=2) {
1036
			$sum_b += ($code{$i});
1037
		}
1038
		if ($len < 13) {
1039
			$sum_b *= 3;
1040
		}
1041
		$r = ($sum_a + $sum_b) % 10;
1042
		if($r > 0) {
1043
			$r = (10 - $r);
1044
		}
1045
		if ($code_len == $data_len) {
1046
			// add check digit
1047
			$code .= $r;
1048
		} elseif ($r !== intval($code{$data_len})) {
1049
			// wrong checkdigit
1050
			return false;
1051
		}
1052
		if ($len == 12) {
1053
			// UPC-A
1054
			$code = '0'.$code;
1055
			++$len;
1056
		}
1057
		if ($upce) {
1058
			// convert UPC-A to UPC-E
1059
			$tmp = substr($code, 4, 3);
1060
			if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) {
1061
				// manufacturer code ends in 000, 100, or 200
1062
				$upce_code = substr($code, 2, 2).substr($code, 9, 3).substr($code, 4, 1);
1063
			} else {
1064
				$tmp = substr($code, 5, 2);
1065
				if ($tmp == '00') {
1066
					// manufacturer code ends in 00
1067
					$upce_code = substr($code, 2, 3).substr($code, 10, 2).'3';
1068
				} else {
1069
					$tmp = substr($code, 6, 1);
1070
					if ($tmp == '0') {
1071
						// manufacturer code ends in 0
1072
						$upce_code = substr($code, 2, 4).substr($code, 11, 1).'4';
1073
					} else {
1074
						// manufacturer code does not end in zero
1075
						$upce_code = substr($code, 2, 5).substr($code, 11, 1);
1076
					}
1077
				}
1078
			}
1079
		}
1080
		//Convert digits to bars
1081
		$codes = array(
1082
			'A'=>array( // left odd parity
1083
				'0'=>'0001101',
1084
				'1'=>'0011001',
1085
				'2'=>'0010011',
1086
				'3'=>'0111101',
1087
				'4'=>'0100011',
1088
				'5'=>'0110001',
1089
				'6'=>'0101111',
1090
				'7'=>'0111011',
1091
				'8'=>'0110111',
1092
				'9'=>'0001011'),
1093
			'B'=>array( // left even parity
1094
				'0'=>'0100111',
1095
				'1'=>'0110011',
1096
				'2'=>'0011011',
1097
				'3'=>'0100001',
1098
				'4'=>'0011101',
1099
				'5'=>'0111001',
1100
				'6'=>'0000101',
1101
				'7'=>'0010001',
1102
				'8'=>'0001001',
1103
				'9'=>'0010111'),
1104
			'C'=>array( // right
1105
				'0'=>'1110010',
1106
				'1'=>'1100110',
1107
				'2'=>'1101100',
1108
				'3'=>'1000010',
1109
				'4'=>'1011100',
1110
				'5'=>'1001110',
1111
				'6'=>'1010000',
1112
				'7'=>'1000100',
1113
				'8'=>'1001000',
1114
				'9'=>'1110100')
1115
		);
1116
		$parities = array(
1117
			'0'=>array('A','A','A','A','A','A'),
1118
			'1'=>array('A','A','B','A','B','B'),
1119
			'2'=>array('A','A','B','B','A','B'),
1120
			'3'=>array('A','A','B','B','B','A'),
1121
			'4'=>array('A','B','A','A','B','B'),
1122
			'5'=>array('A','B','B','A','A','B'),
1123
			'6'=>array('A','B','B','B','A','A'),
1124
			'7'=>array('A','B','A','B','A','B'),
1125
			'8'=>array('A','B','A','B','B','A'),
1126
			'9'=>array('A','B','B','A','B','A')
1127
		);
1128
		$upce_parities = array();
1129
		$upce_parities[0] = array(
1130
			'0'=>array('B','B','B','A','A','A'),
1131
			'1'=>array('B','B','A','B','A','A'),
1132
			'2'=>array('B','B','A','A','B','A'),
1133
			'3'=>array('B','B','A','A','A','B'),
1134
			'4'=>array('B','A','B','B','A','A'),
1135
			'5'=>array('B','A','A','B','B','A'),
1136
			'6'=>array('B','A','A','A','B','B'),
1137
			'7'=>array('B','A','B','A','B','A'),
1138
			'8'=>array('B','A','B','A','A','B'),
1139
			'9'=>array('B','A','A','B','A','B')
1140
		);
1141
		$upce_parities[1] = array(
1142
			'0'=>array('A','A','A','B','B','B'),
1143
			'1'=>array('A','A','B','A','B','B'),
1144
			'2'=>array('A','A','B','B','A','B'),
1145
			'3'=>array('A','A','B','B','B','A'),
1146
			'4'=>array('A','B','A','A','B','B'),
1147
			'5'=>array('A','B','B','A','A','B'),
1148
			'6'=>array('A','B','B','B','A','A'),
1149
			'7'=>array('A','B','A','B','A','B'),
1150
			'8'=>array('A','B','A','B','B','A'),
1151
			'9'=>array('A','B','B','A','B','A')
1152
		);
1153
		$k = 0;
1154
		$seq = '101'; // left guard bar
1155
		if ($upce) {
1156
			$bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1157
			$p = $upce_parities[$code{1}][$r];
1158
			for ($i = 0; $i < 6; ++$i) {
1159
				$seq .= $codes[$p[$i]][$upce_code{$i}];
1160
			}
1161
			$seq .= '010101'; // right guard bar
1162
		} else {
1163
			$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1164
			$half_len = ceil($len / 2);
1165
			if ($len == 8) {
1166
				for ($i = 0; $i < $half_len; ++$i) {
1167
					$seq .= $codes['A'][$code{$i}];
1168
				}
1169
			} else {
1170
				$p = $parities[$code{0}];
1171
				for ($i = 1; $i < $half_len; ++$i) {
1172
					$seq .= $codes[$p[$i-1]][$code{$i}];
1173
				}
1174
			}
1175
			$seq .= '01010'; // center guard bar
1176
			for ($i = $half_len; $i < $len; ++$i) {
1177
				$seq .= $codes['C'][$code{$i}];
1178
			}
1179
			$seq .= '101'; // right guard bar
1180
		}
1181
		$clen = strlen($seq);
1182
		$w = 0;
1183
		for ($i = 0; $i < $clen; ++$i) {
1184
			$w += 1;
1185
			if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq{$i} != $seq{($i+1)}))) {
1186
				if ($seq{$i} == '1') {
1187
					$t = true; // bar
1188
				} else {
1189
					$t = false; // space
1190
				}
1191
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
1192
				$bararray['maxw'] += $w;
1193
				++$k;
1194
				$w = 0;
1195
			}
1196
		}
1197
		return $bararray;
1198
	}
1199
	
1200
	/**
1201
	 * UPC-Based Extentions
1202
	 * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers
1203
	 * 5-Digit Ext.: Used to mark suggested retail price of books
1204
	 * @param string $code code to represent.
1205
	 * @param string $len barcode type: 2 = 2-Digit, 5 = 5-Digit
1206
	 * @return array barcode representation.
1207
	 * @access protected
1208
	 */
1209
	protected function barcode_eanext($code, $len=5) {
1210
		//Padding
1211
		$code = str_pad($code, $len, '0', STR_PAD_LEFT);
1212
		// calculate check digit
1213
		if ($len == 2) {
1214
			$r = $code % 4;
1215
		} elseif ($len == 5) {
1216
			$r = (3 * ($code{0} + $code{2} + $code{4})) + (9 * ($code{1} + $code{3}));
1217
			$r %= 10;
1218
		} else {
1219
			return false;
1220
		}
1221
		//Convert digits to bars
1222
		$codes = array(
1223
			'A'=>array( // left odd parity
1224
				'0'=>'0001101',
1225
				'1'=>'0011001',
1226
				'2'=>'0010011',
1227
				'3'=>'0111101',
1228
				'4'=>'0100011',
1229
				'5'=>'0110001',
1230
				'6'=>'0101111',
1231
				'7'=>'0111011',
1232
				'8'=>'0110111',
1233
				'9'=>'0001011'),
1234
			'B'=>array( // left even parity
1235
				'0'=>'0100111',
1236
				'1'=>'0110011',
1237
				'2'=>'0011011',
1238
				'3'=>'0100001',
1239
				'4'=>'0011101',
1240
				'5'=>'0111001',
1241
				'6'=>'0000101',
1242
				'7'=>'0010001',
1243
				'8'=>'0001001',
1244
				'9'=>'0010111')
1245
		);
1246
		$parities = array();
1247
		$parities[2] = array(
1248
			'0'=>array('A','A'),
1249
			'1'=>array('A','B'),
1250
			'2'=>array('B','A'),
1251
			'3'=>array('B','B')
1252
		);
1253
		$parities[5] = array(
1254
			'0'=>array('B','B','A','A','A'),
1255
			'1'=>array('B','A','B','A','A'),
1256
			'2'=>array('B','A','A','B','A'),
1257
			'3'=>array('B','A','A','A','B'),
1258
			'4'=>array('A','B','B','A','A'),
1259
			'5'=>array('A','A','B','B','A'),
1260
			'6'=>array('A','A','A','B','B'),
1261
			'7'=>array('A','B','A','B','A'),
1262
			'8'=>array('A','B','A','A','B'),
1263
			'9'=>array('A','A','B','A','B')
1264
		);	
1265
		$p = $parities[$len][$r];
1266
		$seq = '1011'; // left guard bar
1267
		$seq .= $codes[$p[0]][$code{0}];
1268
		for ($i = 1; $i < $len; ++$i) {
1269
			$seq .= '01'; // separator
1270
			$seq .= $codes[$p[$i]][$code{$i}];
1271
		}
1272
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1273
		return $this->binseq_to_array($seq, $bararray);
1274
	}
1275
	
1276
	/**
1277
	 * POSTNET and PLANET barcodes.
1278
	 * Used by U.S. Postal Service for automated mail sorting
1279
	 * @param string $code zip code to represent. Must be a string containing a zip code of the form DDDDD or DDDDD-DDDD.
1280
	 * @param boolean $planet if true print the PLANET barcode, otherwise print POSTNET
1281
	 * @return array barcode representation.
1282
	 * @access protected
1283
	 */
1284
	protected function barcode_postnet($code, $planet=false) {
1285
		// bar lenght
1286
		if ($planet) {
1287
			$barlen = Array(
1288
				0 => Array(1,1,2,2,2),
1289
				1 => Array(2,2,2,1,1),
1290
				2 => Array(2,2,1,2,1),
1291
				3 => Array(2,2,1,1,2),
1292
				4 => Array(2,1,2,2,1),
1293
				5 => Array(2,1,2,1,2),
1294
				6 => Array(2,1,1,2,2),
1295
				7 => Array(1,2,2,2,1),
1296
				8 => Array(1,2,2,1,2),
1297
				9 => Array(1,2,1,2,2)
1298
			);
1299
		} else {
1300
			$barlen = Array(
1301
				0 => Array(2,2,1,1,1),
1302
				1 => Array(1,1,1,2,2),
1303
				2 => Array(1,1,2,1,2),
1304
				3 => Array(1,1,2,2,1),
1305
				4 => Array(1,2,1,1,2),
1306
				5 => Array(1,2,1,2,1),
1307
				6 => Array(1,2,2,1,1),
1308
				7 => Array(2,1,1,1,2),
1309
				8 => Array(2,1,1,2,1),
1310
				9 => Array(2,1,2,1,1)
1311
			);
1312
		}
1313
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array());
1314
		$k = 0;
1315
		$code = str_replace('-', '', $code);
1316
		$code = str_replace(' ', '', $code);
1317
		$len = strlen($code);
1318
		// calculate checksum
1319
		$sum = 0;
1320
		for ($i = 0; $i < $len; ++$i) {
1321
			$sum += intval($code{$i});
1322
		}
1323
		$chkd = ($sum % 10);
1324
		if($chkd > 0) {
1325
			$chkd = (10 - $chkd);
1326
		}
1327
		$code .= $chkd;
1328
		$len = strlen($code);
1329
		// start bar
1330
		$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
1331
		$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1332
		$bararray['maxw'] += 2;
1333
		for ($i = 0; $i < $len; ++$i) {
1334
			for ($j = 0; $j < 5; ++$j) {
1335
				$h = $barlen[$code{$i}][$j];
1336
				$p = floor(1 / $h);
1337
				$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
1338
				$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1339
				$bararray['maxw'] += 2;
1340
			}
1341
		}
1342
		// end bar
1343
		$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
1344
		$bararray['maxw'] += 1;
1345
		return $bararray;
1346
	}
1347
	
1348
	/**
1349
	 * RMS4CC - CBC - KIX
1350
	 * RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index)
1351
	 * RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service.
1352
	 * @param string $code code to print
1353
	 * @param boolean $kix if true prints the KIX variation (doesn't use the start and end symbols, and the checksum) - in this case the house number must be sufficed with an X and placed at the end of the code.
1354
	 * @return array barcode representation.
1355
	 * @access protected
1356
	 */
1357
	protected function barcode_rms4cc($code, $kix=false) {
1358
		$notkix = !$kix;
1359
		// bar mode
1360
		// 1 = pos 1, length 2
1361
		// 2 = pos 1, length 3
1362
		// 3 = pos 2, length 1
1363
		// 4 = pos 2, length 2
1364
		$barmode = array(
1365
			'0' => array(3,3,2,2),
1366
			'1' => array(3,4,1,2),
1367
			'2' => array(3,4,2,1),
1368
			'3' => array(4,3,1,2),
1369
			'4' => array(4,3,2,1),
1370
			'5' => array(4,4,1,1),
1371
			'6' => array(3,1,4,2),
1372
			'7' => array(3,2,3,2),
1373
			'8' => array(3,2,4,1),
1374
			'9' => array(4,1,3,2),
1375
			'A' => array(4,1,4,1),
1376
			'B' => array(4,2,3,1),
1377
			'C' => array(3,1,2,4),
1378
			'D' => array(3,2,1,4),
1379
			'E' => array(3,2,2,3),
1380
			'F' => array(4,1,1,4),
1381
			'G' => array(4,1,2,3),
1382
			'H' => array(4,2,1,3),
1383
			'I' => array(1,3,4,2),
1384
			'J' => array(1,4,3,2),
1385
			'K' => array(1,4,4,1),
1386
			'L' => array(2,3,3,2),
1387
			'M' => array(2,3,4,1),
1388
			'N' => array(2,4,3,1),
1389
			'O' => array(1,3,2,4),
1390
			'P' => array(1,4,1,4),
1391
			'Q' => array(1,4,2,3),
1392
			'R' => array(2,3,1,4),
1393
			'S' => array(2,3,2,3),
1394
			'T' => array(2,4,1,3),
1395
			'U' => array(1,1,4,4),
1396
			'V' => array(1,2,3,4),
1397
			'W' => array(1,2,4,3),
1398
			'X' => array(2,1,3,4),
1399
			'Y' => array(2,1,4,3),
1400
			'Z' => array(2,2,3,3)		
1401
		);
1402
		$code = strtoupper($code);
1403
		$len = strlen($code);
1404
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
1405
		if ($notkix) {
1406
			// table for checksum calculation (row,col)
1407
			$checktable = array(
1408
				'0' => array(1,1),
1409
				'1' => array(1,2),
1410
				'2' => array(1,3),
1411
				'3' => array(1,4),
1412
				'4' => array(1,5),
1413
				'5' => array(1,0),
1414
				'6' => array(2,1),
1415
				'7' => array(2,2),
1416
				'8' => array(2,3),
1417
				'9' => array(2,4),
1418
				'A' => array(2,5),
1419
				'B' => array(2,0),
1420
				'C' => array(3,1),
1421
				'D' => array(3,2),
1422
				'E' => array(3,3),
1423
				'F' => array(3,4),
1424
				'G' => array(3,5),
1425
				'H' => array(3,0),
1426
				'I' => array(4,1),
1427
				'J' => array(4,2),
1428
				'K' => array(4,3),
1429
				'L' => array(4,4),
1430
				'M' => array(4,5),
1431
				'N' => array(4,0),
1432
				'O' => array(5,1),
1433
				'P' => array(5,2),
1434
				'Q' => array(5,3),
1435
				'R' => array(5,4),
1436
				'S' => array(5,5),
1437
				'T' => array(5,0),
1438
				'U' => array(0,1),
1439
				'V' => array(0,2),
1440
				'W' => array(0,3),
1441
				'X' => array(0,4),
1442
				'Y' => array(0,5),
1443
				'Z' => array(0,0)
1444
			);
1445
			$row = 0;
1446
			$col = 0;
1447
			for ($i = 0; $i < $len; ++$i) {
1448
				$row += $checktable[$code{$i}][0];
1449
				$col += $checktable[$code{$i}][1];
1450
			}
1451
			$row %= 6;
1452
			$col %= 6;
1453
			$chk = array_keys($checktable, array($row,$col));
1454
			$code .= $chk[0];
1455
			++$len;
1456
		}
1457
		$k = 0;
1458
		if ($notkix) {
1459
			// start bar
1460
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
1461
			$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1462
			$bararray['maxw'] += 2;
1463
		}
1464
		for ($i = 0; $i < $len; ++$i) {
1465
			for ($j = 0; $j < 4; ++$j) {
1466
				switch ($barmode[$code{$i}][$j]) {
1467
					case 1: {
1468
						$p = 0;
1469
						$h = 2;
1470
						break;
1471
					}
1472
					case 2: {
1473
						$p = 0;
1474
						$h = 3;
1475
						break;
1476
					}
1477
					case 3: {
1478
						$p = 1;
1479
						$h = 1;
1480
						break;
1481
					}
1482
					case 4: {
1483
						$p = 1;
1484
						$h = 2;
1485
						break;
1486
					}
1487
				}
1488
				$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
1489
				$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1490
				$bararray['maxw'] += 2;
1491
			}
1492
		}
1493
		if ($notkix) {
1494
			// stop bar
1495
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 3, 'p' => 0);
1496
			$bararray['maxw'] += 1;
1497
		}
1498
		return $bararray;
1499
	}
1500
	
1501
	/**
1502
	 * CODABAR barcodes.
1503
	 * Older code often used in library systems, sometimes in blood banks
1504
	 * @param string $code code to represent.
1505
	 * @return array barcode representation.
1506
	 * @access protected
1507
	 */
1508
	protected function barcode_codabar($code) {
1509
		$chr = array(
1510
			'0' => '11111221',
1511
			'1' => '11112211',
1512
			'2' => '11121121',
1513
			'3' => '22111111',
1514
			'4' => '11211211',
1515
			'5' => '21111211',
1516
			'6' => '12111121',
1517
			'7' => '12112111',
1518
			'8' => '12211111',
1519
			'9' => '21121111',
1520
			'-' => '11122111',
1521
			'$' => '11221111',
1522
			':' => '21112121',
1523
			'/' => '21211121',
1524
			'.' => '21212111',
1525
			'+' => '11222221',
1526
			'A' => '11221211',
1527
			'B' => '12121121',
1528
			'C' => '11121221',
1529
			'D' => '11122211'
1530
		);
1531
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1532
		$k = 0;
1533
		$w = 0;
1534
		$seq = '';
1535
		$code = 'A'.strtoupper($code).'A';
1536
		$len = strlen($code);
1537
		for ($i = 0; $i < $len; ++$i) {
1538
			if (!isset($chr[$code{$i}])) {
1539
				return false;
1540
			}
1541
			$seq = $chr[$code{$i}];
1542
			for ($j = 0; $j < 8; ++$j) {
1543
				if (($j % 2) == 0) {
1544
					$t = true; // bar
1545
				} else {
1546
					$t = false; // space
1547
				}
1548
				$w = $seq{$j};
1549
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
1550
				$bararray['maxw'] += $w;
1551
				++$k;
1552
			}
1553
		}
1554
		return $bararray;
1555
	}
1556
	
1557
	/**
1558
	 * CODE11 barcodes.
1559
	 * Used primarily for labeling telecommunications equipment
1560
	 * @param string $code code to represent.
1561
	 * @return array barcode representation.
1562
	 * @access protected
1563
	 */
1564
	protected function barcode_code11($code) {
1565
		$chr = array(
1566
			'0' => '111121',
1567
			'1' => '211121',
1568
			'2' => '121121',
1569
			'3' => '221111',
1570
			'4' => '112121',
1571
			'5' => '212111',
1572
			'6' => '122111',
1573
			'7' => '111221',
1574
			'8' => '211211',
1575
			'9' => '211111',
1576
			'-' => '112111',
1577
			'S' => '112211'
1578
		);
1579
		
1580
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1581
		$k = 0;
1582
		$w = 0;
1583
		$seq = '';
1584
		$len = strlen($code);
1585
		// calculate check digit C
1586
		$p = 1;
1587
		$check = 0;
1588
		for ($i = ($len - 1); $i >= 0; --$i) {
1589
			$digit = $code{$i};
1590
			if ($digit == '-') {
1591
				$dval = 10;
1592
			} else {
1593
				$dval = intval($digit);
1594
			}
1595
			$check += ($dval * $p);
1596
			++$p;
1597
			if ($p > 10) {
1598
				$p = 1;
1599
			}
1600
		}
1601
		$check %= 11;
1602
		if ($check == 10) {
1603
			$check = '-';
1604
		} 
1605
		$code .= $check;
1606
		if ($len > 10) {
1607
			// calculate check digit K
1608
			$p = 1;
1609
			$check = 0;
1610
			for ($i = $len; $i >= 0; --$i) {
1611
				$digit = $code{$i};
1612
				if ($digit == '-') {
1613
					$dval = 10;
1614
				} else {
1615
					$dval = intval($digit);
1616
				}
1617
				$check += ($dval * $p);
1618
				++$p;
1619
				if ($p > 9) {
1620
					$p = 1;
1621
				}
1622
			}
1623
			$check %= 11;
1624
			$code .= $check;
1625
			++$len;
1626
		}
1627
		$code = 'S'.$code.'S';
1628
		$len += 3;
1629
		for ($i = 0; $i < $len; ++$i) {
1630
			if (!isset($chr[$code{$i}])) {
1631
				return false;
1632
			}
1633
			$seq = $chr[$code{$i}];
1634
			for ($j = 0; $j < 6; ++$j) {
1635
				if (($j % 2) == 0) {
1636
					$t = true; // bar
1637
				} else {
1638
					$t = false; // space
1639
				}
1640
				$w = $seq{$j};
1641
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
1642
				$bararray['maxw'] += $w;
1643
				++$k;
1644
			}
1645
		}
1646
		return $bararray;
1647
	}
1648
	
1649
	/**
1650
	 * Pharmacode
1651
	 * Contains digits (0 to 9)
1652
	 * @param string $code code to represent.
1653
	 * @return array barcode representation.
1654
	 * @access protected
1655
	 */
1656
	protected function barcode_pharmacode($code) {
1657
		$seq = '';
1658
		$code = intval($code);
1659
		while ($code > 0) {
1660
			if (($code % 2) == 0) {
1661
				$seq .= '11100';
1662
				$code -= 2;
1663
			} else {
1664
				$seq .= '100';
1665
				$code -= 1;
1666
			}
1667
			$code /= 2;
1668
		}
1669
		$seq = substr($seq, 0, -2);
1670
		$seq = strrev($seq);
1671
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1672
		return $this->binseq_to_array($seq, $bararray);
1673
	}
1674
	
1675
	/**
1676
	 * Pharmacode two-track
1677
	 * Contains digits (0 to 9)
1678
	 * @param string $code code to represent.
1679
	 * @return array barcode representation.
1680
	 * @access protected
1681
	 */
1682
	protected function barcode_pharmacode2t($code) {
1683
		$seq = '';
1684
		$code = intval($code);
1685
		do {
1686
			switch ($code % 3) {
1687
				case 0: {
1688
					$seq .= '3';
1689
					$code = ($code - 3) / 3;
1690
					break;
1691
				}
1692
				case 1: {
1693
					$seq .= '1';
1694
					$code = ($code - 1) / 3;
1695
					break;
1696
				}
1697
				case 2: {
1698
					$seq .= '2';
1699
					$code = ($code - 2) / 3;
1700
					break;
1701
				}
1702
			}
1703
		} while($code != 0);
1704
		$seq = strrev($seq);
1705
		$k = 0;
1706
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array());
1707
		$len = strlen($seq);
1708
		for ($i = 0; $i < $len; ++$i) {
1709
			switch ($seq{$i}) {
1710
				case '1': {
1711
					$p = 1;
1712
					$h = 1;
1713
					break;
1714
				}
1715
				case '2': {
1716
					$p = 0;
1717
					$h = 1;
1718
					break;
1719
				}
1720
				case '3': {
1721
					$p = 0;
1722
					$h = 2;
1723
					break;
1724
				}
1725
			}
1726
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
1727
			$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1728
			$bararray['maxw'] += 2;
1729
		}
1730
		unset($bararray['bcode'][($k - 1)]);
1731
		--$bararray['maxw'];
1732
		return $bararray;
1733
	}
1734
	
1735
	
1736
	/**
1737
	 * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
1738
	 * (requires PHP bcmath extension) 
1739
	 * Intelligent Mail barcode is a 65-bar code for use on mail in the United States.
1740
	 * The fields are described as follows:<ul><li>The Barcode Identifier shall be assigned by USPS to encode the presort identification that is currently printed in human readable form on the optional endorsement line (OEL) as well as for future USPS use. This shall be two digits, with the second digit in the range of 0–4. The allowable encoding ranges shall be 00–04, 10–14, 20–24, 30–34, 40–44, 50–54, 60–64, 70–74, 80–84, and 90–94.</li><li>The Service Type Identifier shall be assigned by USPS for any combination of services requested on the mailpiece. The allowable encoding range shall be 000http://it2.php.net/manual/en/function.dechex.php–999. Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier values.</li><li>The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000- 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.</li><li>The Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The allowable encoding range shall be 000000000–999999999 when used with a 6 digit Mailer ID and 000000-999999 when used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000–99999,  000000000–999999999, and 00000000000–99999999999.</li></ul>
1741
	 * @param string $code code to print, separate the ZIP (routing code) from the rest using a minus char '-' (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode)
1742
	 * @return array barcode representation.
1743
	 * @access protected
1744
	 */
1745
	protected function barcode_imb($code) {
1746
		$asc_chr = array(4,0,2,6,3,5,1,9,8,7,1,2,0,6,4,8,2,9,5,3,0,1,3,7,4,6,8,9,2,0,5,1,9,4,3,8,6,7,1,2,4,3,9,5,7,8,3,0,2,1,4,0,9,1,7,0,2,4,6,3,7,1,9,5,8);
1747
		$dsc_chr = array(7,1,9,5,8,0,2,4,6,3,5,8,9,7,3,0,6,1,7,4,6,8,9,2,5,1,7,5,4,3,8,7,6,0,2,5,4,9,3,0,1,6,8,2,0,4,5,9,6,7,5,2,6,3,8,5,1,9,8,7,4,0,2,6,3);
1748
		$asc_pos = array(3,0,8,11,1,12,8,11,10,6,4,12,2,7,9,6,7,9,2,8,4,0,12,7,10,9,0,7,10,5,7,9,6,8,2,12,1,4,2,0,1,5,4,6,12,1,0,9,4,7,5,10,2,6,9,11,2,12,6,7,5,11,0,3,2);
1749
		$dsc_pos = array(2,10,12,5,9,1,5,4,3,9,11,5,10,1,6,3,4,1,10,0,2,11,8,6,1,12,3,8,6,4,4,11,0,6,1,9,11,5,3,7,3,10,7,11,8,2,10,3,5,8,0,3,12,11,8,4,5,1,3,0,7,12,9,8,10);
1750
		$code_arr = explode('-', $code);
1751
		$tracking_number = $code_arr[0];
1752
		if (isset($code_arr[1])) {
1753
			$routing_code = $code_arr[1];
1754
		} else {
1755
			$routing_code = '';
1756
		}
1757
		// Conversion of Routing Code
1758
		switch (strlen($routing_code)) {
1759
			case 0: {
1760
				$binary_code = 0;
1761
				break;
1762
			}
1763
			case 5: {
1764
				$binary_code = bcadd($routing_code, '1');
1765
				break;
1766
			}
1767
			case 9: {
1768
				$binary_code = bcadd($routing_code, '100001');
1769
				break;
1770
			}
1771
			case 11: {
1772
				$binary_code = bcadd($routing_code, '1000100001');
1773
				break;
1774
			}
1775
			default: {
0 ignored issues
show
DEFAULT statements must be defined using a colon

As per the PSR-2 coding standard, default statements should not be wrapped in curly braces.

switch ($expr) {
    default: { //wrong
        doSomething();
        break;
    }
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1776
				return false;
1777
				break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1778
			}
1779
		}
1780
		$binary_code = bcmul($binary_code, 10);
1781
		$binary_code = bcadd($binary_code, $tracking_number{0});
1782
		$binary_code = bcmul($binary_code, 5);
1783
		$binary_code = bcadd($binary_code, $tracking_number{1});
1784
		$binary_code .= substr($tracking_number, 2, 18);
1785
		// convert to hexadecimal
1786
		$binary_code = $this->dec_to_hex($binary_code);
1787
		// pad to get 13 bytes
1788
		$binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT);
1789
		// convert string to array of bytes
1790
		$binary_code_arr = chunk_split($binary_code, 2, "\r");
1791
		$binary_code_arr = substr($binary_code_arr, 0, -1);
1792
		$binary_code_arr = explode("\r", $binary_code_arr);
1793
		// calculate frame check sequence
1794
		$fcs = $this->imb_crc11fcs($binary_code_arr);
1795
		// exclude first 2 bits from first byte
1796
		$first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2));
1797
		$binary_code_102bit = $first_byte.substr($binary_code, 2);
1798
		// convert binary data to codewords
1799
		$codewords = array();
1800
		$data = $this->hex_to_dec($binary_code_102bit);
1801
		$codewords[0] = bcmod($data, 636) * 2;
1802
		$data = bcdiv($data, 636);
1803
		for ($i = 1; $i < 9; ++$i) {
1804
			$codewords[$i] = bcmod($data, 1365);
1805
			$data = bcdiv($data, 1365);
1806
		}
1807
		$codewords[9] = $data;
1808
		if (($fcs >> 10) == 1) {
1809
			$codewords[9] += 659;
1810
		}
1811
		// generate lookup tables
1812
		$table2of13 = $this->imb_tables(2, 78);
1813
		$table5of13 = $this->imb_tables(5, 1287);
1814
		// convert codewords to characters
1815
		$characters = array();
1816
		$bitmask = 512;
1817
		foreach($codewords as $k => $val) {
1818
			if ($val <= 1286) {
1819
				$chrcode = $table5of13[$val];
1820
			} else {
1821
				$chrcode = $table2of13[($val - 1287)];
1822
			}
1823
			if (($fcs & $bitmask) > 0) {
1824
				// bitwise invert
1825
				$chrcode = ((~$chrcode) & 8191);
1826
			}
1827
			$characters[] = $chrcode;
1828
			$bitmask /= 2;
1829
		}
1830
		$characters = array_reverse($characters);
1831
		// build bars
1832
		$k = 0;
1833
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
1834
		for ($i = 0; $i < 65; ++$i) {
1835
			$asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0);
1836
			$dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0);
1837
			if ($asc AND $dsc) {
1838
				// full bar (F)
1839
				$p = 0;
1840
				$h = 3;
1841
			} elseif ($asc) {
1842
				// ascender (A)
1843
				$p = 0;
1844
				$h = 2;
1845
			} elseif ($dsc) {
1846
				// descender (D)
1847
				$p = 1;
1848
				$h = 2;
1849
			} else {
1850
				// tracker (T)
1851
				$p = 1;
1852
				$h = 1;
1853
			}
1854
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
1855
			$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1856
			$bararray['maxw'] += 2;
1857
		}
1858
		unset($bararray['bcode'][($k - 1)]);
1859
		--$bararray['maxw'];
1860
		return $bararray;
1861
	}
1862
	
1863
	/**
1864
	 * Convert large integer number to hexadecimal representation.
1865
	 * (requires PHP bcmath extension) 
1866
	 * @param string $number number to convert specified as a string
1867
	 * @return string hexadecimal representation
1868
	 */
1869
	public function dec_to_hex($number) {
1870
		$i = 0;
1871
		$hex = array();
1872
		if($number == 0) {
1873
			return '00';
1874
		}
1875
		while($number > 0) {
1876
			if($number == 0) {
1877
				array_push($hex, '0');
1878
			} else {
1879
				array_push($hex, strtoupper(dechex(bcmod($number, '16'))));
1880
				$number = bcdiv($number, '16', 0);
1881
			}
1882
		}
1883
		$hex = array_reverse($hex);
1884
		return implode($hex);
1885
	}
1886
	
1887
	/**
1888
	 * Convert large hexadecimal number to decimal representation (string).
1889
	 * (requires PHP bcmath extension) 
1890
	 * @param string $hex hexadecimal number to convert specified as a string
1891
	 * @return string hexadecimal representation
1892
	 */
1893
	public function hex_to_dec($hex) {
1894
		$dec = 0;
1895
		$bitval = 1;
1896
		$len = strlen($hex);
1897
		for($pos = ($len - 1); $pos >= 0; --$pos) {
1898
			$dec = bcadd($dec, bcmul(hexdec($hex{$pos}), $bitval));
1899
			$bitval = bcmul($bitval, 16);
1900
		}
1901
		return $dec;
1902
	}	
1903
	
1904
	/**
1905
	 * Intelligent Mail Barcode calculation of Frame Check Sequence
1906
	 * @param string $code_arr array of hexadecimal values (13 bytes holding 102 bits right justified).
1907
	 * @return int 11 bit Frame Check Sequence as integer (decimal base)
1908
	 * @access protected
1909
	 */
1910
	protected function imb_crc11fcs($code_arr) {
1911
		$genpoly = 0x0F35; // generator polynomial
1912
		$fcs = 0x07FF; // Frame Check Sequence
1913
		// do most significant byte skipping the 2 most significant bits
1914
		$data = hexdec($code_arr[0]) << 5;
1915
		for ($bit = 2; $bit < 8; ++$bit) {
1916
			if (($fcs ^ $data) & 0x400) {
1917
				$fcs = ($fcs << 1) ^ $genpoly;
1918
			} else {
1919
				$fcs = ($fcs << 1);
1920
			}
1921
			$fcs &= 0x7FF;
1922
			$data <<= 1;
1923
		}
1924
		// do rest of bytes
1925
		for ($byte = 1; $byte < 13; ++$byte) {
1926
			$data = hexdec($code_arr[$byte]) << 3;
1927
			for ($bit = 0; $bit < 8; ++$bit) {
1928
				if (($fcs ^ $data) & 0x400) {
1929
					$fcs = ($fcs << 1) ^ $genpoly;
1930
				} else {
1931
					$fcs = ($fcs << 1);
1932
				}
1933
				$fcs &= 0x7FF;
1934
				$data <<= 1;
1935
			}
1936
		}
1937
		return $fcs;		
1938
	}
1939
	
1940
	/**
1941
	 * Reverse unsigned short value
1942
	 * @param int $num value to reversr
1943
	 * @return int reversed value
1944
	 * @access protected
1945
	 */
1946
	protected function imb_reverse_us($num) {
1947
		$rev = 0;
1948
		for ($i = 0; $i < 16; ++$i) {
1949
			$rev <<= 1;
1950
			$rev |= ($num & 1);
1951
			$num >>= 1;
1952
		}
1953
		return $rev;
1954
	}
1955
	
1956
	/**
1957
	 * generate Nof13 tables used for Intelligent Mail Barcode
1958
	 * @param int $n is the type of table: 2 for 2of13 table, 5 for 5of13table
1959
	 * @param int $size size of table (78 for n=2 and 1287 for n=5)
1960
	 * @return array requested table
1961
	 * @access protected
1962
	 */
1963
	protected function imb_tables($n, $size) {
1964
		$table = array();
1965
		$lli = 0; // LUT lower index
1966
		$lui = $size - 1; // LUT upper index
1967
		for ($count = 0; $count < 8192; ++$count) {
1968
			$bit_count = 0;
1969
			for ($bit_index = 0; $bit_index < 13; ++$bit_index) {
1970
				$bit_count += intval(($count & (1 << $bit_index)) != 0);
1971
			}
1972
			// if we don't have the right number of bits on, go on to the next value
1973
			if ($bit_count == $n) {
1974
				$reverse = ($this->imb_reverse_us($count) >> 3);
1975
				// if the reverse is less than count, we have already visited this pair before
1976
				if ($reverse >= $count) {
1977
					// If count is symmetric, place it at the first free slot from the end of the list.
1978
					// Otherwise, place it at the first free slot from the beginning of the list AND place $reverse ath the next free slot from the beginning of the list
1979
					if ($reverse == $count) {
1980
						$table[$lui] = $count;
1981
						--$lui;
1982
					} else {
1983
						$table[$lli] = $count;
1984
						++$lli;
1985
						$table[$lli] = $reverse;
1986
						++$lli;
1987
					}
1988
				}
1989
			}
1990
		}
1991
		return $table;
1992
	}
1993
	
1994
} // end of class
1995
1996
//============================================================+
1997
// END OF FILE                                                 
1998
//============================================================+
1999
?>
2000