<?php
/***************************************************
 *          Kody kreskowe - RSS-14 Limited         *
 ***************************************************
 * Ostatnia modyfikacja: 01.11.2012 (wersja 1.0)   *
 * Autor: Jacek Kowalski (http://jacekk.info)      *
 *                                                 *
 * Strona WWW: http://jacekk.info/scripts/barcodes *
 *                                                 *
 * Utwór rozprowadzany na licencji                 *
 * http://creativecommons.org/licenses/by-nc/2.5/  *
 ***************************************************/

/* Kodowanie znaków UTF-8 */

function combins($n$r) {
    if(
$n-$r $r) {
        
$minDenom $r;
        
$maxDenom $n-$r;
    }
    else
    {
        
$minDenom $n-$r;
        
$maxDenom $r;
    }
    
$val 1;
    
$j 1;
    for(
$i $n$i $maxDenom$i--) {
        
$val *= $i;
        if(
$j <= $minDenom) {
            
$val /= $j;
            
$j++;
        }
    }
    for(; 
$j <= $minDenom$j++) {
        
$val /= $j;
    }
    return 
$val;
}


/* Zgodnie z załącznikiem B do PN-ISO/IEC 24724:2009 */
// n - num of modules
function getRSSwidths($val$n$elements$maxWidth$noNarrow=TRUE)
{
    
$narrowMask 0;
    for(
$bar 0$bar $elements-1$bar++) {
        for(
$elmWidth 1$narrowMask |= (1<<$bar); ; $elmWidth++, $narrowMask &= ~(1<<$bar)) {
            
/* get all combinations */
            
$subVal combins($n-$elmWidth-1$elements-$bar-2);
            
/* less combinations with no single-module element */
            
if((!$noNarrow) && ($narrowMask == 0) && ($n-$elmWidth-($elements-$bar-1) >= $elements-$bar-1)) {
                
$subVal -= combins($n-$elmWidth-($elements-$bar), $elements-$bar-2);
            }
            
/* less combinations with elements > maxVal */
            
if($elements-$bar-1) {
                
$lessVal 0;
                for(
$mxwElement $n-$elmWidth-($elements-$bar-2); $mxwElement $maxWidth$mxwElement--) {
                    
$lessVal += combins($n-$elmWidth-$mxwElement-1$elements-$bar-3);
                }
                
$subVal -= $lessVal * ($elements-1-$bar);
            }
            elseif(
$n-$elmWidth $maxWidth) {
                
$subVal--;
            }
            
$val -= $subVal;
            if(
$val 0) break;
        }
        
$val += $subVal;
        
$n -= $elmWidth;
        
$widths[$bar] = $elmWidth;
    }
    
$widths[$bar] = $n;
    return 
$widths;
}

/* Zwraca kod jaki trzeba przekazać do funkcji getRSSwidths,
 * by uzyskać szerokości elementów słów kodowych */
function getEncodingValue($val) {
    
$table = array(
        
// group_max, Gsum, Todd, Teven, odd_modules, even_modules, odd_widest, even_widest
        
array(    183063,        0,        6538,    28,    17,    9,    6,    3),
        array(    
820063,        183064,        875,    7282,    13,    13,    5,    4),
        array(    
1000775,    820064,        28,    6454,    9,    17,    3,    6),
        array(    
1491020,    1000776,    2415,    2034,    15,    11,    5,    4),
        array(    
1979844,    1491021,    203,    2408,    11,    15,    4,    5),
        array(    
1996938,    1979845,    17094,    1,    19,    7,    8,    1),
        array(    
2013570,    1996939,    1,    16632,    7,    19,    1,    8),
    );
    
    foreach(
$table as $key) {
        if(
$key[0]<$val) continue;
        
        return array(
            
// (val - Gsum) div Teven
            
'odd' => (int)bcdiv(($val-$key[1]), $key[3]),
            
'odd_modules' => $key[4],
            
'odd_widest' => $key[6],
            
// (val - Gsum) mod Teven
            
'even' => (int)bcmod(($val-$key[1]), $key[3]),
            
'even_modules' => $key[5],
            
'even_widest' => $key[7],
        );
    }
    
    throw new 
Exception('Błąd w funkcji getEncodingValue - OutOfBound');
}

$kod $_GET['kod'];
if(!
ctype_digit($kod) || strlen($kod)>13 || (substr($kod, -131)!=&& substr($kod, -131)!=1) ) {
    die(
'Kod musi mieć 13 cyfr (bez cyfry kontrolnej) - pierwsza 0 lub 1');
}

$code = array(
    
=> array(),
    
=> array(),
);

/* Pierwszy moduł, lewy */
$d getEncodingValue(bcdiv($kod2013571));
$d_odd getRSSwidths($d['odd'], $d['odd_modules'], 7$d['odd_widest']);
$d_even getRSSwidths($d['even'], $d['even_modules'], 7$d['even_widest']);

for(
$i=0$i<7$i++) {
    
$code[1][] = $d_odd[$i];
    
$code[1][] = $d_even[$i];
}

/* Drugi moduł, prawy */
$d getEncodingValue(bcmod($kod2013571));
$d_odd getRSSwidths($d['odd'], $d['odd_modules'], 7$d['odd_widest']);
$d_even getRSSwidths($d['even'], $d['even_modules'], 7$d['even_widest']);


for(
$i=0$i<7$i++) {
    
$code[2][] = $d_odd[$i];
    
$code[2][] = $d_even[$i];
}

function 
controlCharacter($c) {
    
$wagi = array(
        
=> array(1392781651751641442372266),
        
=> array(20602618547341341339288474),
    );
    
    
$sum 0;
    for(
$i=1$i<=2$i++) {
        foreach(
$c[$i] as $k => $n) {
            
$sum += $wagi[$i][$k]*$n;
            
$sum %= 89;
        }
    }
    
    return 
$sum;
}

$controlCharTable_seq = array(012345678910111213141516171819202122232425262728293031323334353637383940414243455257636465667374757677787982126127128129130132141142143144145146210211212213214215216217220316317318319320322323326337);

/* Znak kontrolny, środek */
$d $controlCharTable_seq[controlCharacter($code)];
$d_odd getRSSwidths(bcdiv($d21), 8631);
$d_even getRSSwidths(bcmod($d21), 8631);

for(
$i=0$i<6$i++) {
    
$code['c'][] = $d_odd[$i];
    
$code['c'][] = $d_even[$i];
}
$code['c'][] = 1;
$code['c'][] = 1;

unset(
$d$d_odd$d_even$controlCharTable_seq$control);

$code array_merge(array(11), $code[1], $code['c'], $code[2], array(11));

$code_bin '';
$now FALSE;
foreach(
$code as $len) {
    if(
$now) {
        
$code_bin .= str_repeat('1'$len);
    }
    else
    {
        
$code_bin .= str_repeat('0'$len);
    }
    
    
$now = !$now;
}

unset(
$code$now$len);

$code_bin str_split($code_bin);

$img imagecreate(7410);
$wht imagecolorallocate($img255255255);
$blc imagecolorallocate($img000);

foreach(
$code_bin as $n => $el) {
    if(
$el == '1') {
        
imageline($img$n1$n30$blc);
    }
}

header('Content-Type: image/png');
imagepng($img);
?>