public static function parse($unparsed) { $iban = strtolower(str_replace(' ', '', $unparsed)); $countries = ['al' => 28, 'ad' => 24, 'at' => 20, 'az' => 28, 'bh' => 22, 'be' => 16, 'ba' => 20, 'br' => 29, 'bg' => 22, 'cr' => 21, 'hr' => 21, 'cy' => 28, 'cz' => 24, 'dk' => 18, 'do' => 28, 'ee' => 20, 'fo' => 18, 'fi' => 18, 'fr' => 27, 'ge' => 22, 'de' => 22, 'gi' => 23, 'gr' => 27, 'gl' => 18, 'gt' => 28, 'hu' => 28, 'is' => 26, 'ie' => 22, 'il' => 23, 'it' => 27, 'jo' => 30, 'kz' => 20, 'kw' => 30, 'lv' => 21, 'lb' => 28, 'li' => 21, 'lt' => 20, 'lu' => 20, 'mk' => 19, 'mt' => 31, 'mr' => 27, 'mu' => 30, 'mc' => 27, 'md' => 24, 'me' => 22, 'nl' => 18, 'no' => 15, 'pk' => 24, 'ps' => 29, 'pl' => 28, 'pt' => 25, 'qa' => 29, 'ro' => 24, 'sm' => 27, 'sa' => 24, 'rs' => 22, 'sk' => 24, 'si' => 19, 'es' => 24, 'se' => 24, 'ch' => 21, 'tn' => 24, 'tr' => 26, 'ae' => 23, 'gb' => 22, 'vg' => 24]; $chars = ['a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15, 'g' => 16, 'h' => 17, 'i' => 18, 'j' => 19, 'k' => 20, 'l' => 21, 'm' => 22, 'n' => 23, 'o' => 24, 'p' => 25, 'q' => 26, 'r' => 27, 's' => 28, 't' => 29, 'u' => 30, 'v' => 31, 'w' => 32, 'x' => 33, 'y' => 34, 'z' => 35]; if (!array_key_exists(substr($iban, 0, 2), $countries)) { throw new Exception('Country code ' . strtoupper(substr($iban, 0, 2)) . ' seems not valid'); } if (strlen($iban) == $countries[substr($iban, 0, 2)]) { $movedchar = substr($iban, 4) . substr($iban, 0, 4); $movedchar_array = str_split($movedchar); $newstring = ''; foreach ($movedchar_array as $key => $value) { if (!is_numeric($movedchar_array[$key])) { $movedchar_array[$key] = $chars[$movedchar_array[$key]]; } $newstring .= $movedchar_array[$key]; } if (bcmod($newstring, '97') == 1) { return new static(['country' => strtoupper(substr($iban, 0, 2)), 'routing' => substr($iban, 2, 13), 'number' => substr($iban, 15), 'complete' => strtoupper($iban)]); } else { throw new Exception('IBAN ' . $unparsed . ' seems not valid!'); } } else { throw new Exception('IBAN ' . $unparsed . ' seems not valid!'); } }
/** * 10进制转其它进制 * * @access public * @param String $dec 十进制数据 * @param String $toRadix 要转换的进制 * @return String */ public static function dec2Any($dec, $toRadix) { $MIN_RADIX = 2; $MAX_RADIX = 62; $num62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; if ($toRadix < $MIN_RADIX || $toRadix > $MAX_RADIX) { $toRadix = 2; } if ($toRadix == 10) { return $dec; } $buf = array(); $charPos = 64; $isNegative = $dec < 0; if (!$isNegative) { $dec = -$dec; } while (bccomp($dec, -$toRadix) <= 0) { $buf[$charPos--] = $num62[-bcmod($dec, $toRadix)]; $dec = bcdiv($dec, $toRadix); } $buf[$charPos] = $num62[-$dec]; if ($isNegative) { $buf[--$charPos] = '-'; } $_any = ''; for ($i = $charPos; $i < 65; $i++) { $_any .= $buf[$i]; } return $_any; }
/** * 生成UUID 单机使用 * @access public * @return string */ public static function uuid() { list($usec, $sec) = explode(" ", microtime(false)); $usec = (string) ($usec * 10000000); $timestamp = bcadd(bcadd(bcmul($sec, "10000000"), (string) $usec), "621355968000000000"); $ticks = bcdiv($timestamp, 10000); $maxUint = 4294967295; $high = bcdiv($ticks, $maxUint) + 0; $low = bcmod($ticks, $maxUint) - $high; $highBit = pack("N*", $high); $lowBit = pack("N*", $low); $guid = str_pad(dechex(ord($highBit[2])), 2, "0", STR_PAD_LEFT) . str_pad(dechex(ord($highBit[3])), 2, "0", STR_PAD_LEFT) . str_pad(dechex(ord($lowBit[0])), 2, "0", STR_PAD_LEFT) . str_pad(dechex(ord($lowBit[1])), 2, "0", STR_PAD_LEFT) . "-" . str_pad(dechex(ord($lowBit[2])), 2, "0", STR_PAD_LEFT) . str_pad(dechex(ord($lowBit[3])), 2, "0", STR_PAD_LEFT) . "-"; $chars = "abcdef0123456789"; for ($i = 0; $i < 4; $i++) { $guid .= $chars[mt_rand(0, 15)]; } $guid .= "-"; for ($i = 0; $i < 4; $i++) { $guid .= $chars[mt_rand(0, 15)]; } $guid .= "-"; for ($i = 0; $i < 12; $i++) { $guid .= $chars[mt_rand(0, 15)]; } return $guid; }
function convBase($numberInput, $fromBaseInput, $toBaseInput) { if ($fromBaseInput == $toBaseInput) { return $numberInput; } $fromBase = str_split($fromBaseInput, 1); $toBase = str_split($toBaseInput, 1); $number = str_split($numberInput, 1); $fromLen = strlen($fromBaseInput); $toLen = strlen($toBaseInput); $numberLen = strlen($numberInput); $retval = ''; $base10 = ''; if ($toBaseInput == '0123456789') { $retval = 0; for ($i = 1; $i <= $numberLen; $i++) { $retval = bcadd($retval, bcmul(array_search($number[$i - 1], $fromBase), bcpow($fromLen, $numberLen - $i))); } return $retval; } if ($fromBaseInput != '0123456789') { $base10 = convBase($numberInput, $fromBaseInput, '0123456789'); } else { $base10 = $numberInput; } if ($base10 < strlen($toBaseInput)) { return $toBase[$base10]; } while ($base10 != '0') { $retval = $toBase[bcmod($base10, $toLen)] . $retval; $base10 = bcdiv($base10, $toLen, 0); } return $retval; }
function bcdechex($dec, $digits = false) { $hex = ''; $positive = $dec < 0 ? false : true; while ($dec) { $hex .= dechex(abs(bcmod($dec, '16'))); $dec = bcdiv($dec, '16', 0); } if ($digits) { while (strlen($hex) < $digits) { $hex .= '0'; } } if ($positive) { return strrev($hex); } for ($i = 0; $isset($hex[$i]); $i++) { $hex[$i] = dechex(15 - hexdec($hex[$i])); } for ($i = 0; isset($hex[$i]) && $hex[$i] == 'f'; $i++) { $hex[$i] = '0'; } if (isset($hex[$i])) { $hex[$i] = dechex(hexdec($hex[$i]) + 1); } return strrev($hex); }
/** * Generate a valid prime based on which php is used. Slower than the Prime generator. * @return \Generator */ public static function generator() { $primes = ['2']; $currentNumber = '2'; (yield '2'); while (true) { ++$currentNumber; $unitNumber = (int) substr($currentNumber, -1); if (($currentNumber & 1) === 0) { continue; } $squareRoot = bcsqrt($currentNumber); $foundPrimeDivisor = false; foreach ($primes as $prime) { if (bccomp($prime, $squareRoot) === 1) { break; } if (bcmod($currentNumber, $prime) === '0') { $foundPrimeDivisor = true; break; } } if (!$foundPrimeDivisor) { $primes[] = $currentNumber; (yield $currentNumber); } } }
/** * Iban validator. * * @author petitchevalroux * @licence originale http://creativecommons.org/licenses/by-sa/2.0/fr/ * * @link http://dev.petitchevalroux.net/php/validation-iban-php.356.html + comments & links * * @param string $iban * * @return bool */ public static function validate($iban) { /*Régles de validation par pays*/ static $rules = array('AL' => '[0-9]{8}[0-9A-Z]{16}', 'AD' => '[0-9]{8}[0-9A-Z]{12}', 'AT' => '[0-9]{16}', 'BE' => '[0-9]{12}', 'BA' => '[0-9]{16}', 'BG' => '[A-Z]{4}[0-9]{6}[0-9A-Z]{8}', 'HR' => '[0-9]{17}', 'CY' => '[0-9]{8}[0-9A-Z]{16}', 'CZ' => '[0-9]{20}', 'DK' => '[0-9]{14}', 'EE' => '[0-9]{16}', 'FO' => '[0-9]{14}', 'FI' => '[0-9]{14}', 'FR' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'PF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'TF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'GP' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'MQ' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'YT' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'NC' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'RE' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'BL' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'MF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'PM' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'WF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'GE' => '[0-9A-Z]{2}[0-9]{16}', 'DE' => '[0-9]{18}', 'GI' => '[A-Z]{4}[0-9A-Z]{15}', 'GR' => '[0-9]{7}[0-9A-Z]{16}', 'GL' => '[0-9]{14}', 'HU' => '[0-9]{24}', 'IS' => '[0-9]{22}', 'IE' => '[0-9A-Z]{4}[0-9]{14}', 'IL' => '[0-9]{19}', 'IT' => '[A-Z][0-9]{10}[0-9A-Z]{12}', 'KZ' => '[0-9]{3}[0-9A-Z]{3}[0-9]{10}', 'KW' => '[A-Z]{4}[0-9]{22}', 'LV' => '[A-Z]{4}[0-9A-Z]{13}', 'LB' => '[0-9]{4}[0-9A-Z]{20}', 'LI' => '[0-9]{5}[0-9A-Z]{12}', 'LT' => '[0-9]{16}', 'LU' => '[0-9]{3}[0-9A-Z]{13}', 'MK' => '[0-9]{3}[0-9A-Z]{10}[0-9]{2}', 'MT' => '[A-Z]{4}[0-9]{5}[0-9A-Z]{18}', 'MR' => '[0-9]{23}', 'MU' => '[A-Z]{4}[0-9]{19}[A-Z]{3}', 'MC' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'ME' => '[0-9]{18}', 'NL' => '[A-Z]{4}[0-9]{10}', 'NO' => '[0-9]{11}', 'PL' => '[0-9]{24}', 'PT' => '[0-9]{21}', 'RO' => '[A-Z]{4}[0-9A-Z]{16}', 'SM' => '[A-Z][0-9]{10}[0-9A-Z]{12}', 'SA' => '[0-9]{2}[0-9A-Z]{18}', 'RS' => '[0-9]{18}', 'SK' => '[0-9]{20}', 'SI' => '[0-9]{15}', 'ES' => '[0-9]{20}', 'SE' => '[0-9]{20}', 'CH' => '[0-9]{5}[0-9A-Z]{12}', 'TN' => '[0-9]{20}', 'TR' => '[0-9]{5}[0-9A-Z]{17}', 'AE' => '[0-9]{19}', 'GB' => '[A-Z]{4}[0-9]{14}', 'CI' => '[0-9A-Z]{2}[0-9]{22}'); /*On vérifie la longueur minimale*/ if (mb_strlen($iban) < 15) { return false; } /*On récupère le code ISO du pays*/ $ctr = substr($iban, 0, 2); if (isset($rules[$ctr]) === false) { return false; } /*On récupère la règle de validation en fonction du pays*/ $check = substr($iban, 4); /*Si la règle n'est pas bonne l'IBAN n'est pas valide*/ if (preg_match('~^' . $rules[$ctr] . '$~', $check) !== 1) { return false; } /*On récupère la chaine qui permet de calculer la validation*/ $check = $check . substr($iban, 0, 4); /*On remplace les caractères alpha par leurs valeurs décimales*/ $check = str_replace(array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'), array('10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'), $check); /*On effectue la vérification finale*/ return bcmod($check, 97) === '1'; }
function GetAuthID($i64friendID) { $tmpfriendID = $i64friendID; $iServer = "1"; if (extension_loaded('bcmath') == 1) { //decode communityid with bcmath if (bcmod($i64friendID, "2") == "0") { $iServer = "0"; } $tmpfriendID = bcsub($tmpfriendID, $iServer); if (bccomp("76561197960265728", $tmpfriendID) == -1) { $tmpfriendID = bcsub($tmpfriendID, "76561197960265728"); } $tmpfriendID = bcdiv($tmpfriendID, "2"); return "STEAM_0:" . $iServer . ":" . $tmpfriendID; } else { if (extension_loaded('gmp') == 1) { //decode communityid with gmp if (gmp_mod($i64friendID, "2") == "0") { $iServer = "0"; } $tmpfriendID = gmp_sub($tmpfriendID, $iServer); if (gmp_cmp("76561197960265728", $tmpfriendID) == -1) { $tmpfriendID = gmp_sub($tmpfriendID, "76561197960265728"); } $tmpfriendID = gmp_div($tmpfriendID, "2"); return "STEAM_0:" . $iServer . ":" . gmp_strval($tmpfriendID); } } return false; }
function is_prime($n, $k) { if ($n == 2) { return true; } if ($n < 2 || $n % 2 == 0) { return false; } $d = $n - 1; $s = 0; while ($d % 2 == 0) { $d /= 2; $s++; } for ($i = 0; $i < $k; $i++) { $a = rand(2, $n - 1); $x = bcpowmod($a, $d, $n); if ($x == 1 || $x == $n - 1) { continue; } for ($j = 1; $j < $s; $j++) { $x = bcmod(bcmul($x, $x), $n); if ($x == 1) { return false; } if ($x == $n - 1) { continue 2; } } return false; } return true; }
function sphPack64($v) { assert(is_numeric($v)); // x64 route if (PHP_INT_SIZE >= 8) { $i = (int) $v; return pack("NN", $i >> 32, $i & (1 << 32) - 1); } // x32 route, bcmath $x = "4294967296"; if (function_exists("bcmul")) { $h = bcdiv($v, $x, 0); $l = bcmod($v, $x); return pack("NN", (double) $h, (double) $l); // conversion to float is intentional; int would lose 31st bit } // x32 route, 15 or less decimal digits // we can use float, because its actually double and has 52 precision bits if (strlen($v) <= 15) { $f = (double) $v; $h = (int) ($f / $x); $l = (int) ($f - $x * $h); return pack("NN", $h, $l); } // x32 route, 16 or more decimal digits // well, let me know if you *really* need this die("INTERNAL ERROR: packing more than 15-digit numeric on 32-bit PHP is not implemented yet (contact support)"); }
function decode_username($hash) { if (!$hash) { return 'invalid_name'; } $username = ''; while ($hash) { $i = bcmod($hash, 37); $hash = bcdiv($hash, 37); if ($i == '0') { $username = '******' . $username; } else { if ($i < 27) { if (bcmod($hash, 37) == '0') { $username = chr($i + 65 - 1) . $username; } else { $username = chr($i + 97 - 1) . $username; } } else { $username = chr($i + 48 - 27) . $username; } } } return $username; }
function checkIBAN($iban) { $iban = strtolower(str_replace(' ', '', $iban)); $Countries = array('al' => 28, 'ad' => 24, 'at' => 20, 'az' => 28, 'bh' => 22, 'be' => 16, 'ba' => 20, 'br' => 29, 'bg' => 22, 'cr' => 21, 'hr' => 21, 'cy' => 28, 'cz' => 24, 'dk' => 18, 'do' => 28, 'ee' => 20, 'fo' => 18, 'fi' => 18, 'fr' => 27, 'ge' => 22, 'de' => 22, 'gi' => 23, 'gr' => 27, 'gl' => 18, 'gt' => 28, 'hu' => 28, 'is' => 26, 'ie' => 22, 'il' => 23, 'it' => 27, 'jo' => 30, 'kz' => 20, 'kw' => 30, 'lv' => 21, 'lb' => 28, 'li' => 21, 'lt' => 20, 'lu' => 20, 'mk' => 19, 'mt' => 31, 'mr' => 27, 'mu' => 30, 'mc' => 27, 'md' => 24, 'me' => 22, 'nl' => 18, 'no' => 15, 'pk' => 24, 'ps' => 29, 'pl' => 28, 'pt' => 25, 'qa' => 29, 'ro' => 24, 'sm' => 27, 'sa' => 24, 'rs' => 22, 'sk' => 24, 'si' => 19, 'es' => 24, 'se' => 24, 'ch' => 21, 'tn' => 24, 'tr' => 26, 'ae' => 23, 'gb' => 22, 'vg' => 24); $Chars = array('a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15, 'g' => 16, 'h' => 17, 'i' => 18, 'j' => 19, 'k' => 20, 'l' => 21, 'm' => 22, 'n' => 23, 'o' => 24, 'p' => 25, 'q' => 26, 'r' => 27, 's' => 28, 't' => 29, 'u' => 30, 'v' => 31, 'w' => 32, 'x' => 33, 'y' => 34, 'z' => 35); if (!isset($Countries[substr($iban, 0, 2)])) { return false; } if (strlen($iban) == $Countries[substr($iban, 0, 2)]) { $MovedChar = substr($iban, 4) . substr($iban, 0, 4); $MovedCharArray = str_split($MovedChar); $NewString = ""; foreach ($MovedCharArray as $key => $value) { if (!is_numeric($MovedCharArray[$key])) { $MovedCharArray[$key] = $Chars[$MovedCharArray[$key]]; } $NewString .= $MovedCharArray[$key]; } if (bcmod($NewString, '97') == 1) { return TRUE; } else { return FALSE; } } else { return FALSE; } }
/** * Checks social security numbers numbers for France * * @param string $check The value to check. * @return boolean * @access public */ function ssn($check) { $pattern = '/^[12]\\d{2}(0\\d|1[012])(\\d{2}|2[AB])(\\d{6}|\\d{8})$/'; if (!preg_match($pattern, $check)) { return false; } // No key to check if (strlen($check) == 13) { return true; } $numberWithoutKey = substr($check, 0, -2); $key = substr($check, -2); // Corse special cases // source : http://xml.insee.fr/schema/nir.html // check : http://www.parodie.com/monetique/nir.htm if ($numberWithoutKey[6] == 'A') { $numberWithoutKey = str_replace('A', '0', $numberWithoutKey); $numberWithoutKey -= 1000000; } elseif ($numberWithoutKey[6] == 'B') { $numberWithoutKey = str_replace('B', '0', $numberWithoutKey); $numberWithoutKey -= 2000000; } // bcmod works with large numbers where % doesn't $expectedKey = 97 - bcmod($numberWithoutKey, 97); return $expectedKey == $key; }
/** * @param $str string * @param $frombase int * @param $tobase int * * @return string * * Converts integers from base to another. */ public static function baseConvert($str, $frombase = 10, $tobase = 36) { $str = trim($str); if (intval($frombase) != 10) { $len = strlen($str); $q = 0; for ($i = 0; $i < $len; $i++) { $r = base_convert($str[$i], $frombase, 10); $q = bcadd(bcmul($q, $frombase), $r); } } else { $q = $str; } if (intval($tobase) != 10) { $s = ''; while (bccomp($q, '0', 0) > 0) { $r = intval(bcmod($q, $tobase)); $s = base_convert($r, 10, $tobase) . $s; $q = bcdiv($q, $tobase, 0); } } else { $s = $q; } return $s; }
/** * Convert a large arbitrary number between arbitrary bases * * Works the same as the php version but supports large arbitrary numbers by using BCMath * * @see http://php.net/manual/en/function.base-convert.php * @see http://php.net/manual/en/function.base-convert.php#109660 * @param string $number * @param int $frombase * @param int $tobase * @return string */ function base_convert($number, $frombase, $tobase) { if ($frombase == $tobase) { return $number; } $number = trim($number); if ($frombase != 10) { $len = strlen($number); $fromDec = 0; for ($i = 0; $i < $len; $i++) { $v = \base_convert($number[$i], $frombase, 10); $fromDec = bcadd(bcmul($fromDec, $frombase, 0), $v, 0); } } else { $fromDec = $number; } if ($tobase != 10) { $result = ''; while (bccomp($fromDec, '0', 0) > 0) { $v = intval(bcmod($fromDec, $tobase)); $result = \base_convert($v, 10, $tobase) . $result; $fromDec = bcdiv($fromDec, $tobase, 0); } } else { $result = $fromDec; } return (string) $result; }
function powmod($base, $exponent, $modulus) { if (function_exists('gmp_powm')) { // fast return gmp_strval(gmp_powm($base, $exponent, $modulus)); } if (function_exists('bi_powmod')) { // not tested return bi_sto_str(bi_powmod($base, $exponent, $modulus)); } if (function_exists('bcpowmod')) { // slow return bcpowmod($base, $exponent, $modulus); } // emulation, slow $square = bcmod($base, $modulus); $result = 1; while (bccomp($exponent, 0) > 0) { if (bcmod($exponent, 2)) { $result = bcmod(bcmul($result, $square), $modulus); } $square = bcmod(bcmul($square, $square), $modulus); $exponent = bcdiv($exponent, 2); } return $result; }
public function encode($password) { $this->codificar .= $password . $this->salt; $len = strlen($this->codificar); for ($i = 0; $i < $len; $i++) { #Funciòn ORD() devuelve el valor entero ASCII de un caracter. $e = ord(strtolower($this->codificar[$i])); $this->repreNumerica1 .= $e; } #Se realiza la primera iteración: $this->repreNumerica2 = bcmod($this->repreNumerica1, trim(fgets($this->file))); #Ciclo que lleva a cabo el resto de las iteraciones: while (!feof($this->file)) { #Se lee desde el archivo de entrada el valor que será el divisor en cada iteración: $modulus = fgets($this->file); #Validación para asegurar que la lectura no es el valor booleano "false": if ($modulus) { #Se realiza el módulo: $this->repreNumerica2 = bcmod($this->repreNumerica2, trim($modulus)); } } $len = strlen($this->repreNumerica2); #Se convierte la representación numérica resultante en una cadena de caracteres que representa el Hash final: for ($i = 0; $i < $len; $i++) { #Se convierte el dígito en un caracter de la tabla ASCII. $this->hash .= chr($this->repreNumerica2[$i] + 61); } fclose($this->file); return $this->hash; }
/** * Iban validator. * * @author petitchevalroux * @licence originale http://creativecommons.org/licenses/by-sa/2.0/fr/ * * @link http://dev.petitchevalroux.net/php/validation-iban-php.356.html + comments & links * * @param string $iban * * @return bool */ public static function validate($iban) { // Per country validation rules static $rules = array('AL' => '[0-9]{8}[0-9A-Z]{16}', 'AD' => '[0-9]{8}[0-9A-Z]{12}', 'AT' => '[0-9]{16}', 'BE' => '[0-9]{12}', 'BA' => '[0-9]{16}', 'BG' => '[A-Z]{4}[0-9]{6}[0-9A-Z]{8}', 'HR' => '[0-9]{17}', 'CY' => '[0-9]{8}[0-9A-Z]{16}', 'CZ' => '[0-9]{20}', 'DK' => '[0-9]{14}', 'EE' => '[0-9]{16}', 'FO' => '[0-9]{14}', 'FI' => '[0-9]{14}', 'FR' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'PF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'TF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'GP' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'MQ' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'YT' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'NC' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'RE' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'BL' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'MF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'PM' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'WF' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'GE' => '[0-9A-Z]{2}[0-9]{16}', 'DE' => '[0-9]{18}', 'GI' => '[A-Z]{4}[0-9A-Z]{15}', 'GR' => '[0-9]{7}[0-9A-Z]{16}', 'GL' => '[0-9]{14}', 'HU' => '[0-9]{24}', 'IS' => '[0-9]{22}', 'IE' => '[0-9A-Z]{4}[0-9]{14}', 'IL' => '[0-9]{19}', 'IT' => '[A-Z][0-9]{10}[0-9A-Z]{12}', 'KZ' => '[0-9]{3}[0-9A-Z]{3}[0-9]{10}', 'KW' => '[A-Z]{4}[0-9]{22}', 'LV' => '[A-Z]{4}[0-9A-Z]{13}', 'LB' => '[0-9]{4}[0-9A-Z]{20}', 'LI' => '[0-9]{5}[0-9A-Z]{12}', 'LT' => '[0-9]{16}', 'LU' => '[0-9]{3}[0-9A-Z]{13}', 'MK' => '[0-9]{3}[0-9A-Z]{10}[0-9]{2}', 'MT' => '[A-Z]{4}[0-9]{5}[0-9A-Z]{18}', 'MR' => '[0-9]{23}', 'MU' => '[A-Z]{4}[0-9]{19}[A-Z]{3}', 'MC' => '[0-9]{10}[0-9A-Z]{11}[0-9]{2}', 'ME' => '[0-9]{18}', 'NL' => '[A-Z]{4}[0-9]{10}', 'NO' => '[0-9]{11}', 'PL' => '[0-9]{24}', 'PT' => '[0-9]{21}', 'RO' => '[A-Z]{4}[0-9A-Z]{16}', 'SM' => '[A-Z][0-9]{10}[0-9A-Z]{12}', 'SA' => '[0-9]{2}[0-9A-Z]{18}', 'RS' => '[0-9]{18}', 'SK' => '[0-9]{20}', 'SI' => '[0-9]{15}', 'ES' => '[0-9]{20}', 'SE' => '[0-9]{20}', 'CH' => '[0-9]{5}[0-9A-Z]{12}', 'TN' => '[0-9]{20}', 'TR' => '[0-9]{5}[0-9A-Z]{17}', 'AE' => '[0-9]{19}', 'GB' => '[A-Z]{4}[0-9]{14}', 'CI' => '[0-9A-Z]{2}[0-9]{22}'); // Min length check if (mb_strlen($iban) < 15) { return false; } // Fetch country code from IBAN $ctr = substr($iban, 0, 2); if (isset($rules[$ctr]) === false) { return false; } // Fetch country validation rule $check = substr($iban, 4); if (preg_match('~^' . $rules[$ctr] . '$~', $check) !== 1) { return false; } // Fetch needed string for validation $check = $check . substr($iban, 0, 4); // Replace characters by decimal values $check = str_replace(array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'), array('10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'), $check); // Final check return bcmod($check, 97) === '1'; }
/** * * @convert seconds to hours minutes and seconds * * @param int $seconds The number of seconds * * @return string * */ private function secondsToWords($seconds) { /*** return value ***/ $ret = ['weeks' => 0, 'days' => 0, 'hours' => 0, 'minutes' => 0, 'seconds' => 0]; /*** get the weeks ***/ $ret['weeks'] = intval($seconds) / (60 * 60 * 24 * 7); /*** get the days ***/ $ret['days'] = bcmod(intval($seconds) / (60 * 60 * 24), 7); /*** get the hours ***/ $ret['hours'] = bcmod(intval($seconds) / 3600, 60); if ($ret['hours'] >= 24) { $ret['hours'] = bcmod($ret['hours'], 24); } /*** get the minutes ***/ $ret['minutes'] = bcmod(intval($seconds) / 60, 60); /*** get the seconds ***/ $ret['seconds'] = bcmod(intval($seconds), 60); $daysString = ""; if ($ret['weeks'] >= 1) { $daysString = sprintf("%d week%s ", $ret['weeks'], $ret['weeks'] >= 2 ? 's' : ''); // $ret['days'] = bcmod($ret['days'], 7); } if ($ret['days'] > 0) { $daysString = sprintf("%s%d day%s ", $daysString, $ret['days'], $ret['days'] > 1 ? 's' : ''); } return sprintf("%s%02d:%02d:%02d", $daysString, $ret['hours'], $ret['minutes'], $ret['seconds']); }
/** * Check to see if an integer is a single bit, or a combination * * @param int $bit Bit to check * * @return bool */ public static function isSingleBit($bit) { if ($bit == 1) { return true; } return $bit > 0 && bcmod($bit, 2) == 0 && ($bit & $bit - 1) == 0; }
/** * @see http://php.net/manual/en/function.base-convert.php#106546 * * @param $numberInput * @param $fromBaseInput * @param $toBaseInput * * @return int|string */ protected static function convertBase($numberInput, $fromBaseInput, $toBaseInput) { if ($fromBaseInput == $toBaseInput) { return $numberInput; } $fromBase = str_split($fromBaseInput, 1); $toBase = str_split($toBaseInput, 1); $number = str_split($numberInput, 1); $fromLen = strlen($fromBaseInput); $toLen = strlen($toBaseInput); $numberLen = strlen($numberInput); $retval = ''; if ($toBaseInput == self::FORMAT_NUMBER) { $retval = 0; for ($i = 1; $i <= $numberLen; $i++) { $retval = bcadd($retval, bcmul(array_search($number[$i - 1], $fromBase), bcpow($fromLen, $numberLen - $i))); } return $retval; } if ($fromBaseInput != self::FORMAT_NUMBER) { $base10 = self::convertBase($numberInput, $fromBaseInput, self::FORMAT_NUMBER); } else { $base10 = $numberInput; } if ($base10 < strlen($toBaseInput)) { return $toBase[$base10]; } while ($base10 != '0') { $retval = $toBase[bcmod($base10, $toLen)] . $retval; $base10 = bcdiv($base10, $toLen, 0); } return $retval; }
function decode_base58($btcaddress) { // Compute big base58 number: $chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; $n = "0"; for ($i = 0; $i < strlen($btcaddress); $i++) { $p1 = strpos($chars, $btcaddress[$i]); if ($p1 === false) { return false; } $n = bcmul($n, "58"); $n = bcadd($n, (string) $p1); } // Peel off bytes to get checksum / hash / version: $checksum = ""; for ($i = 0; $i < 4; $i++) { $byte = bcmod($n, "256"); $checksum = chr((int) $byte) . $checksum; $n = bcdiv($n, "256"); } $hash = ""; for ($i = 0; $i < 20; $i++) { $byte = bcmod($n, "256"); $hash = chr((int) $byte) . $hash; $n = bcdiv($n, "256"); } $version = (int) $n; // Make sure checksum is correct: $check = hash('sha256', hash('sha256', chr($version) . $hash, true), true); if (substr($check, 0, 4) != $checksum) { return false; } return array($version, $hash, $checksum); }
/** * * {@inheritdoc} * * @see \vxPHP\Constraint\AbstractConstraint::validate() */ public function validate($value) { $this->clearErrorMessage(); $iban = strtolower(preg_replace('/\\s+/', '', $value)); // no IBAN exceeds 34 chars and starts with country code and checksum if (!preg_match('/^[a-z]{2}[0-9]{2}[a-z0-9]{1,30}$/', $iban)) { $this->setErrorMessage('IBAN does not meet formal requirements.'); return FALSE; } // IBAN must provide a valid country code and match the country's IBAN length if (!isset($this->countriesLength[substr($iban, 0, 2)]) || strlen($iban) !== $this->countriesLength[substr($iban, 0, 2)]) { $this->setErrorMessage('IBAN with unknown country code.'); return FALSE; } // rearrange country code and checksum $movedChar = substr($iban, 4) . substr($iban, 0, 4); $movedCharArray = str_split($movedChar); $newString = ''; $codeA = ord('a') - 10; foreach ($movedCharArray as $key) { // replace characters if (!is_numeric($key)) { // a is mapped to 10, b to 11, ... z ... 35 $key = ord($key) - $codeA; } $newString .= $key; } $result = bcmod($newString, '97') === '1'; if (!$result) { $this->setErrorMessage('IBAN checksum failed.'); } return $result; }
function bcinvert($a, $n) { // Sanity check if (!is_scalar($a)) { user_error('bcinvert() expects parameter 1 to be string, ' . gettype($a) . ' given', E_USER_WARNING); return false; } if (!is_scalar($n)) { user_error('bcinvert() expects parameter 2 to be string, ' . gettype($n) . ' given', E_USER_WARNING); return false; } $u1 = $v2 = '1'; $u2 = $v1 = '0'; $u3 = $n; $v3 = $a; while (bccomp($v3, '0')) { $q0 = bcdiv($u3, $v3); $t1 = bcsub($u1, bcmul($q0, $v1)); $t2 = bcsub($u2, bcmul($q0, $v2)); $t3 = bcsub($u3, bcmul($q0, $v3)); $u1 = $v1; $u2 = $v2; $u3 = $v3; $v1 = $t1; $v2 = $t2; $v3 = $t3; } if (bccomp($u2, '0') < 0) { return bcadd($u2, $n); } else { return bcmod($u2, $n); } }
public static function shorten($num, $minLength, $chars = null, $affine = 0) { if (!$num) { return null; } $chars = str_split($chars ? $chars : self::$chars); $base = $divider = count($chars); if ($minLength > 1) { $num = bcadd($num, bcsub(bcpow($base, $minLength - 1), 1)); } $pos = 0; $add = $affine; $ret = array(); while ($num > 0) { $r = bcmod($num, $base); $num = bcdiv($num, $base); if (strpos($num, ".")) { $num = substr($num, 0, strpos($num, ".")); } if ($affine) { $r = ($r + $add + $pos) % $base; $add = $r; } $ret[$pos] = $chars[$r]; $pos++; } return implode("", array_reverse($ret)); }
/** * Replace bcpowmod() * * @category PHP * @package PHP_Compat * @license LGPL - http://www.gnu.org/licenses/lgpl.html * @copyright 2004-2007 Aidan Lister <*****@*****.**>, Arpad Ray <*****@*****.**> * @link http://php.net/function.bcpowmod * @author Sara Golemon <*****@*****.**> * @version $Revision: 1.1 $ * @since PHP 5.0.0 * @require PHP 4.0.0 (user_error) */ function php_compat_bcpowmod($x, $y, $modulus, $scale = 0) { // Sanity check if (!is_scalar($x)) { user_error('bcpowmod() expects parameter 1 to be string, ' . gettype($x) . ' given', E_USER_WARNING); return false; } if (!is_scalar($y)) { user_error('bcpowmod() expects parameter 2 to be string, ' . gettype($y) . ' given', E_USER_WARNING); return false; } if (!is_scalar($modulus)) { user_error('bcpowmod() expects parameter 3 to be string, ' . gettype($modulus) . ' given', E_USER_WARNING); return false; } if (!is_scalar($scale)) { user_error('bcpowmod() expects parameter 4 to be integer, ' . gettype($scale) . ' given', E_USER_WARNING); return false; } $t = '1'; while (bccomp($y, '0')) { if (bccomp(bcmod($y, '2'), '0')) { $t = bcmod(bcmul($t, $x), $modulus); $y = bcsub($y, '1'); } $x = bcmod(bcmul($x, $x), $modulus); $y = bcdiv($y, '2'); } return $t; }
public static function checkAddress($address) { $origbase58 = $address; $dec = "0"; for ($i = 0; $i < strlen($address); $i++) { $dec = bcadd(bcmul($dec, "58", 0), strpos("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", substr($address, $i, 1)), 0); } $address = ""; while (bccomp($dec, 0) == 1) { $dv = bcdiv($dec, "16", 0); $rem = (int) bcmod($dec, "16"); $dec = $dv; $address = $address . substr("0123456789ABCDEF", $rem, 1); } $address = strrev($address); for ($i = 0; $i < strlen($origbase58) && substr($origbase58, $i, 1) == "1"; $i++) { $address = "00" . $address; } if (strlen($address) % 2 != 0) { $address = "0" . $address; } if (strlen($address) != 50) { return false; } if (hexdec(substr($address, 0, 2)) > 0) { return false; } return substr(strtoupper(hash("sha256", hash("sha256", pack("H*", substr($address, 0, strlen($address) - 8)), true))), 0, 8) == substr($address, strlen($address) - 8); }
protected static function decodeAddress($data) { $charsetHex = '0123456789ABCDEF'; $charsetB58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; $raw = "0"; for ($i = 0; $i < strlen($data); $i++) { $current = (string) strpos($charsetB58, $data[$i]); $raw = (string) bcmul($raw, "58", 0); $raw = (string) bcadd($raw, $current, 0); } $hex = ""; while (bccomp($raw, 0) == 1) { $dv = (string) bcdiv($raw, "16", 0); $rem = (int) bcmod($raw, "16"); $raw = $dv; $hex = $hex . $charsetHex[$rem]; } $withPadding = strrev($hex); for ($i = 0; $i < strlen($data) && $data[$i] == "1"; $i++) { $withPadding = "00" . $withPadding; } if (strlen($withPadding) % 2 != 0) { $withPadding = "0" . $withPadding; } return $withPadding; }
/** * Pack a long. * * If it is a 32bit PHP we suppose that this log is treated by bcmath * TODO 32bit * * @param int|string $value * * @return string the packed long */ public static function packLong($value) { if (PHP_INT_SIZE > 4) { $value = (int) $value; $binaryString = chr($value >> 56 & 0xff) . chr($value >> 48 & 0xff) . chr($value >> 40 & 0xff) . chr($value >> 32 & 0xff) . chr($value >> 24 & 0xff) . chr($value >> 16 & 0xff) . chr($value >> 8 & 0xff) . chr($value & 0xff); } else { /* * To get the two's complement of a binary number, * the bits are inverted, or "flipped", * by using the bitwise NOT operation; * the value of 1 is then added to the resulting value */ $bitString = ''; $isNegative = $value[0] == '-'; if (function_exists("bcmod")) { //add 1 for the two's complement if ($isNegative) { $value = bcadd($value, '1'); } while ($value !== '0') { $bitString = (string) abs((int) bcmod($value, '2')) . $bitString; $value = bcdiv($value, '2'); } } elseif (function_exists("gmp_mod")) { //add 1 for the two's complement if ($isNegative) { $value = gmp_strval(gmp_add($value, '1')); } while ($value !== '0') { $bitString = gmp_strval(gmp_abs(gmp_mod($value, '2'))) . $bitString; $value = gmp_strval(gmp_div_q($value, '2')); } } else { while ($value != 0) { list($value, $remainder) = self::str2bin((string) $value); $bitString = $remainder . $bitString; } } //Now do the logical not for the two's complement last phase if ($isNegative) { $len = strlen($bitString); for ($x = 0; $x < $len; $x++) { $bitString[$x] = $bitString[$x] == '1' ? '0' : '1'; } } //pad to have 64 bit if ($bitString != '' && $isNegative) { $bitString = str_pad($bitString, 64, '1', STR_PAD_LEFT); } else { $bitString = str_pad($bitString, 64, '0', STR_PAD_LEFT); } $hi = substr($bitString, 0, 32); $lo = substr($bitString, 32, 32); $hiBin = pack('H*', str_pad(base_convert($hi, 2, 16), 8, 0, STR_PAD_LEFT)); $loBin = pack('H*', str_pad(base_convert($lo, 2, 16), 8, 0, STR_PAD_LEFT)); $binaryString = $hiBin . $loBin; } return $binaryString; }
/** * Modulus in PHP and BCMATH works differently than the original package expects: * PHP: -4 % 1024 = -4 * Python: -4 % 1024 = 1020 * * This function mimics the Python behaviour using BCMATH. * * @param $a LargeInt * @param $b LargeInt * @return LargeInt */ function bc_unsigned_mod($a, $b) { $c = bcmod($a, $b); if (bccomp($c, "0") === BCMATH_COMP_LEFT_SMALLER) { $c = bcadd($c, $b); } return $c; }