示例#1
0
 /**
  * Convert this number into a other number-system.
  *
  * @param NumberSystem $newSystem
  *
  * @return Number
  */
 public function convert(NumberSystem $newSystem)
 {
     $newDigits = [];
     $decimalValue = gmp_init($this->decimalValue());
     do {
         $divisionResult = gmp_div_qr($decimalValue, $newSystem->getBase());
         $remainder = gmp_strval($divisionResult[1]);
         $decimalValue = $divisionResult[0];
         $newDigits[] = $newSystem->getSymbolForPosition($remainder);
     } while (gmp_strval($decimalValue) > 0);
     return $newSystem->buildNumber(array_reverse($newDigits));
 }
示例#2
0
文件: home.php 项目: senusop/myRepo
 public function kirim_chat()
 {
     $this->load->view("fungsiRSA");
     /* 
     		-- keterangan Masing Masing Fungsi yang dipake dari Library gmp --
     gmp_div_qr = Bagi;
     		gmp_add    = Tambah;
     		gmp_mul    = Kali;
     		gmp_sub    = Kurang;
     		gmp_gcd    = Menghitung Nilai phi;
     		gmp_strval = Convert Nomer ke String;
     */
     // Inisialisasi P = 113 & Q = 157 (Masing Masing adalah Bilangan Prima) <--- Lebih Besar Lebih Bagus
     // Menghitung N = P*Q
     $n = gmp_mul(113, 157);
     $valn = gmp_strval($n);
     // Menghitung Nilai M =(p-1)*(q-1)
     $m = gmp_mul(gmp_sub(113, 1), gmp_sub(157, 1));
     // Mencari E (Kunci Public --> (e,n))
     // Inisialisasi E = 5
     // Membuktikan E = FPB (Faktor Persekutuan Terbesar) dari E dan M = 1
     for ($e = 5; $e < 1000; $e++) {
         // Mencoba dengan Perulangan 1000 Kali
         $fpb = gmp_gcd($e, $m);
         if (gmp_strval($fpb) == '1') {
             // Jika Benar E adalah FPB dari E dan M = 1 <-- Hentikan Proses
             break;
         }
     }
     // Menghitung D (Kunci Private --> (d,n))
     // D = (($m * $i) + 1) / e = $key[1] <-- Perulangan Do While
     $i = 1;
     do {
         $key = gmp_div_qr(gmp_add(gmp_mul($m, $i), 1), $e);
         $i++;
         if ($i == 1000) {
             // Dengan Perulangan 1000 Kali
             break;
         }
     } while (gmp_strval($key[1]) != '0');
     // Hasil D = $key[0]
     $d = $key[0];
     $vald = gmp_strval($d);
     $user = $this->input->post("user");
     $pesan = $this->input->post("pesan");
     $userid = $this->input->post("iduser");
     $hasilenkripsi = enkripsi($pesan, $n, $e);
     $insert = "insert into chat (user,pesan,id_user) VALUES ('{$user}','{$hasilenkripsi}','{$userid}')";
     $this->db->query($insert);
     redirect("home/ambil_pesan");
 }
示例#3
0
 function bcdiv($a, $b, $precision = NULL)
 {
     $qr = gmp_div_qr($a, $b);
     $q = gmp_strval($qr[0]);
     $r = gmp_strval($qr[1]);
     if (!$r || $precision === 0) {
         return $q;
     } else {
         if (isset($precision)) {
             $r = substr($r, 0, $precision);
         }
         return "{$q}.{$r}";
     }
 }
示例#4
0
function base58_encode($string)
{
    $table = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
    $long_value = gmp_init(bin2hex($string), 16);
    $result = '';
    while (gmp_cmp($long_value, 58) > 0) {
        list($long_value, $mod) = gmp_div_qr($long_value, 58);
        $result .= $table[gmp_intval($mod)];
    }
    $result .= $table[gmp_intval($long_value)];
    for ($nPad = 0; $string[$nPad] == ""; ++$nPad) {
    }
    return str_repeat($table[0], $nPad) . strrev($result);
}
示例#5
0
 protected static function _decodeFromDER(Identifier $identifier, $data, &$offset)
 {
     $idx = $offset;
     $len = Length::expectFromDER($data, $idx)->length();
     $subids = self::_decodeSubIDs(substr($data, $idx, $len));
     $idx += $len;
     // decode first subidentifier according to spec section 8.19.4
     if (isset($subids[0])) {
         list($x, $y) = gmp_div_qr($subids[0], "40");
         array_splice($subids, 0, 1, array($x, $y));
     }
     $offset = $idx;
     return new self(self::_implodeSubIDs(...$subids));
 }
 public function convertFractions(array $number)
 {
     $target = gmp_init($this->target->getRadix());
     $dividend = $this->getDecimal($number);
     $divisor = $this->getDecimal([$this->source->getDigit(1)] + array_fill(1, max(count($number), 1), $this->source->getDigit(0)));
     $digits = $this->getFractionDigitCount(count($number));
     $zero = gmp_init('0');
     $result = [];
     for ($i = 0; $i < $digits && gmp_cmp($dividend, $zero) > 0; $i++) {
         list($digit, $dividend) = gmp_div_qr(gmp_mul($dividend, $target), $divisor);
         $result[] = gmp_intval($digit);
     }
     return $this->target->getDigits(empty($result) ? [0] : $result);
 }
示例#7
0
function show_mini_orderbook_table_cell($id, $curr, $price, $have, $want, $fiat_depth, $btc_depth)
{
    // $have and $want is what the 'worst priced' existing order has and wants, and is used here to set the price
    // $fiat_depth and $btc_depth are combined amounts available which we want to match, and may include orders at better prices
    // $curr is the currency type they want
    if ($curr == 'BTC') {
        // we are selling BTC
        $depth = $btc_depth;
        $p = clean_sql_numstr(bcdiv($have, $want, 8));
    } else {
        // we are buying BTC
        $depth = $fiat_depth;
        $p = clean_sql_numstr(bcdiv($want, $have, 8));
    }
    list($w, $r) = gmp_div_qr(gmp_mul($depth, $have), $want);
    $w = gmp_strval(gmp_cmp($r, 0) ? gmp_sub($w, 1) : $w);
    $h = gmp_strval($depth);
    active_table_cell_trade($id, 'l', internal_to_numstr($btc_depth, BTC_PRECISION), "?page=trade&in={$curr}&have={$h}&want={$w}&rate={$p}", 'right');
    active_table_cell_trade($id, 'r', internal_to_numstr($fiat_depth, FIAT_PRECISION), "?page=trade&in={$curr}&have={$h}&want={$w}&rate={$p}", 'right');
}
 /**
  * Encode a binary string to base58
  *
  * @param $binary
  * @return string
  * @throws \Exception
  */
 protected function encodeBase58($binary_bitcoin_address)
 {
     $size = strlen($binary_bitcoin_address);
     if ($size == 0) {
         return '';
     }
     $orig = $binary_bitcoin_address;
     $decimal = gmp_import($binary_bitcoin_address);
     $return = "";
     while (gmp_cmp($decimal, 0) > 0) {
         list($decimal, $rem) = gmp_div_qr($decimal, 58);
         $return = $return . self::$BASE_58_CHARS[gmp_intval($rem)];
     }
     $return = strrev($return);
     //leading zeros
     for ($i = 0; $i < $size && $orig[$i] == ""; $i++) {
         $return = "1" . $return;
     }
     return $return;
 }
function CantorExpand($n, $x)
{
    //參數說明
    // $n - 排列的位數
    // $x - 第幾個 (必須要是字串)
    //1. $x 先減1
    $x = gmp_sub($x, "1");
    $str = "";
    for ($i = 1; $i <= $n; $i++) {
        //2. 先算($n-$i)階乘
        $fac = gmp_strval(gmp_fact($n - $i));
        //3. 再算 $x / ($n-$i) 的商跟餘數
        $res = gmp_div_qr($x, $fac);
        $quotient = gmp_strval($res[0]);
        $remainder = gmp_strval($res[1]);
        //4. 比這個位數小的數目總共有 $quotient 個,所以開始找出這個位數
        $str .= findMax($quotient);
        //5. 把餘數設為 $x,下次要使用
        $x = $remainder;
    }
    return $str;
}
示例#10
0
function fulfill_order($our_orderid)
{
    $our = fetch_order_info($our_orderid);
    if ($our->status != 'OPEN') {
        return;
    }
    if ($our->processed) {
        throw new Error('Unprocessed', "Shouldn't be here for {$our_orderid}");
    }
    // Dividing two bignum(20) values only gives us 4 decimal places in the result
    // this can cause us to process the matching orders out of sequence unless we arrange
    // for the quotient to be greater than 1 by putting the bigger value on top.
    //
    // With BTC at around 10 GBP each, I just saw the previous version of this query
    // process 2 orders out of sequence because the values of initial_want_amount / initial_amount
    // for the two orders were 0.09348 and 0.09346, which compare equal to 4 decimal places
    if ($our->initial_amount > $our->initial_want_amount) {
        $order_by = "initial_want_amount / initial_amount ASC";
    } else {
        $order_by = "initial_amount / initial_want_amount DESC";
    }
    $query = "\n        SELECT orderid, uid\n        FROM orderbook\n        WHERE\n            status='OPEN'\n            AND processed=TRUE\n            AND type='{$our->want_type}'\n            AND want_type='{$our->type}'\n            AND initial_amount * '{$our->initial_amount}' >= initial_want_amount * '{$our->initial_want_amount}'\n            AND uid!='{$our->uid}'\n        ORDER BY {$order_by}, timest ASC;\n    ";
    wait_for_lock($our->uid);
    $result = b_query($query);
    while ($row = mysql_fetch_array($result)) {
        echo "Found matching ", $row['orderid'], " from user ", $row['uid'], ".\n";
        wait_for_lock($row['uid']);
        // lock their account
        $them = fetch_order_info($row['orderid']);
        // re-fetch their order now that they're locked
        if ($them->status != 'OPEN') {
            echo "order {$them->orderid} was cancelled on us\n";
            release_lock($them->uid);
            continue;
        }
        printf("old order: has %s; wants %s\n", internal_to_numstr($them->amount), internal_to_numstr($them->want_amount));
        if ($them->type != $our->want_type || $our->type != $them->want_type) {
            throw Error('Problem', 'Urgent problem. Contact the site owner IMMEDIATELY.');
        }
        // echo "  them: orderid {$them->orderid}, uid {$them->uid}, have {$them->amount} {$them->type}, want {$them->want_amount}\n";
        // echo "  us: orderid {$our->orderid}, uid {$our->uid }, have: {$our->amount} {$our->type}, want {$our->want_amount}\n";
        // echo "  them->initial_amount = {$them->initial_amount}, them->initial_want_amount = {$them->initial_want_amount}\n";
        $left = gmp_mul($our->amount, $them->initial_amount);
        $right = gmp_mul($them->amount, $them->initial_want_amount);
        if (gmp_cmp($left, $right) >= 0) {
            // We need to calculate how much of our stuff they can afford at their price
            // we ignore the remainder - it's totally insignificant.
            list($them->new_want, $remainder) = gmp_div_qr($right, $them->initial_amount);
            if (gmp_cmp($remainder, 0) != 0) {
                $them->new_want = gmp_add($them->new_want, 1);
            }
            $them->new_want = gmp_strval($them->new_want);
            echo "    we swallow them; they can afford {$them->new_want} from us\n";
            pacman($them->orderid, $them->uid, $them->amount, $them->type, $them->commission, $our->orderid, $our->uid, $them->new_want, $our->type, $our->commission, $our->amount, $our->initial_amount, $our->initial_want_amount);
            release_lock($them->uid);
            // re-update as still haven't finished...
            // info needed for any further transactions
            $our = fetch_order_info($our->orderid);
            // order was closed and our job is done.
            if ($our->status != 'OPEN') {
                break;
            }
        } else {
            // We need to calculate how much of their stuff we can afford at their price
            // we ignore the remainder - it's totally insignificant.
            list($our->new_want, $remainder) = gmp_div_qr($left, $them->initial_want_amount);
            if (gmp_cmp($remainder, 0) != 0) {
                $our->new_want = gmp_add($our->new_want, 1);
            }
            $our->new_want = gmp_strval($our->new_want);
            echo "    they swallow us; we can afford {$our->new_want} from them\n";
            pacman($our->orderid, $our->uid, $our->amount, $our->type, $our->commission, $them->orderid, $them->uid, $our->new_want, $our->want_type, $them->commission, $them->amount, $them->initial_amount, $them->initial_want_amount);
            release_lock($them->uid);
            break;
        }
    }
    release_lock($our->uid);
}
 public static function gmpSatoshisToFloatBTC($value)
 {
     /*{{{*/
     $result = gmp_div_qr($value, gmp_init('100000000'));
     $whole = gmp_strval($result[0]);
     $fraction = sprintf('%08s', gmp_strval($result[1]));
     $btc = floatval("{$whole}.{$fraction}");
     return $btc;
 }
示例#12
0
 /**
  * Divides two BigIntegers.
  *
  * Returns an array whose first element contains the quotient and whose second element contains the
  * "common residue".  If the remainder would be positive, the "common residue" and the remainder are the
  * same.  If the remainder would be negative, the "common residue" is equal to the sum of the remainder
  * and the divisor.
  *
  * Here's a quick 'n dirty example:
  * <code>
  * <?php
  *    include('Math/BigInteger.php');
  *
  *    $a = new Math_BigInteger('10');
  *    $b = new Math_BigInteger('20');
  *
  *    list($quotient,$remainder) = $a->divide($b);
  *
  *    echo $quotient->toString(); // outputs 0
  *    echo "\r\n";
  *    echo $remainder->toString(); // outputs 10
  * ?>
  * </code>
  *
  * @param Math_BigInteger $y
  * @return Array
  * @access public
  * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}
  *    with a slight variation due to the fact that this script, initially, did not support negative numbers.  Now,
  *    it does, but I don't want to change that which already works.
  */
 function divide($y)
 {
     switch (MATH_BIGINTEGER_MODE) {
         case MATH_BIGINTEGER_MODE_GMP:
             $quotient = new Math_BigInteger();
             $remainder = new Math_BigInteger();
             list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
             if (gmp_sign($remainder->value) < 0) {
                 $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
             }
             return array($quotient, $remainder);
         case MATH_BIGINTEGER_MODE_BCMATH:
             $quotient = new Math_BigInteger();
             $remainder = new Math_BigInteger();
             $quotient->value = bcdiv($this->value, $y->value);
             $remainder->value = bcmod($this->value, $y->value);
             if ($remainder->value[0] == '-') {
                 $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value);
             }
             return array($quotient, $remainder);
     }
     $x = $this->_copy();
     $y = $y->_copy();
     $x_sign = $x->is_negative;
     $y_sign = $y->is_negative;
     $x->is_negative = $y->is_negative = false;
     $diff = $x->compare($y);
     if (!$diff) {
         $temp = new Math_BigInteger();
         $temp->value = array(1);
         $temp->is_negative = $x_sign != $y_sign;
         return array($temp, new Math_BigInteger());
     }
     if ($diff < 0) {
         // if $x is negative, "add" $y.
         if ($x_sign) {
             $x = $y->subtract($x);
         }
         return array(new Math_BigInteger(), $x);
     }
     // normalize $x and $y as described in HAC 14.23 / 14.24
     // (incidently, i haven't been able to find a definitive example showing that this
     // results in worth-while speedup, but whatever)
     $msb = $y->value[count($y->value) - 1];
     for ($shift = 0; !($msb & 0x2000000); $shift++) {
         $msb <<= 1;
     }
     $x->_lshift($shift);
     $y->_lshift($shift);
     $x_max = count($x->value) - 1;
     $y_max = count($y->value) - 1;
     $quotient = new Math_BigInteger();
     $quotient->value = $this->_array_repeat(0, $x_max - $y_max + 1);
     // $temp = $y << ($x_max - $y_max-1) in base 2**26
     $temp = new Math_BigInteger();
     $temp->value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y->value);
     while ($x->compare($temp) >= 0) {
         // calculate the "common residue"
         $quotient->value[$x_max - $y_max]++;
         $x = $x->subtract($temp);
         $x_max = count($x->value) - 1;
     }
     for ($i = $x_max; $i >= $y_max + 1; $i--) {
         $x_value = array($x->value[$i], $i > 0 ? $x->value[$i - 1] : 0, $i - 1 > 0 ? $x->value[$i - 2] : 0);
         $y_value = array($y->value[$y_max], $y_max > 0 ? $y_max - 1 : 0);
         $q_index = $i - $y_max - 1;
         if ($x_value[0] == $y_value[0]) {
             $quotient->value[$q_index] = 0x3ffffff;
         } else {
             $quotient->value[$q_index] = floor(($x_value[0] * 0x4000000 + $x_value[1]) / $y_value[0]);
         }
         $temp = new Math_BigInteger();
         $temp->value = array($y_value[1], $y_value[0]);
         $lhs = new Math_BigInteger();
         $lhs->value = array($quotient->value[$q_index]);
         $lhs = $lhs->multiply($temp);
         $rhs = new Math_BigInteger();
         $rhs->value = array($x_value[2], $x_value[1], $x_value[0]);
         while ($lhs->compare($rhs) > 0) {
             $quotient->value[$q_index]--;
             $lhs = new Math_BigInteger();
             $lhs->value = array($quotient->value[$q_index]);
             $lhs = $lhs->multiply($temp);
         }
         $corrector = new Math_BigInteger();
         $temp = new Math_BigInteger();
         $corrector->value = $temp->value = $this->_array_repeat(0, $q_index);
         $temp->value[] = $quotient->value[$q_index];
         $temp = $temp->multiply($y);
         if ($x->compare($temp) < 0) {
             $corrector->value[] = 1;
             $x = $x->add($corrector->multiply($y));
             $quotient->value[$q_index]--;
         }
         $x = $x->subtract($temp);
         $x_max = count($x->value) - 1;
     }
     // unnormalize the remainder
     $x->_rshift($shift);
     $quotient->is_negative = $x_sign != $y_sign;
     // calculate the "common residue", if appropriate
     if ($x_sign) {
         $y->_rshift($shift);
         $x = $y->subtract($x);
     }
     return array($quotient->_normalize(), $x);
 }
 protected function assetIdToName($asset_id)
 {
     // BTC = 'BTC'
     // XCP = 'XCP'
     if ($asset_id === 0) {
         return 'BTC';
     }
     if ($asset_id === 1) {
         return 'XCP';
     }
     $b26_digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
     if ($asset_id < pow(26, 3)) {
         throw new Exception("asset ID was too low (" . json_encode($asset_id, 192) . ")", 1);
     }
     # Divide that integer into Base 26 string.
     $asset_name = '';
     $n = gmp_init($asset_id);
     while (gmp_cmp($n, 0) > 0) {
         list($n, $r) = gmp_div_qr($n, 26, GMP_ROUND_ZERO);
         $asset_name = substr($b26_digits, gmp_intval($r), 1) . $asset_name;
     }
     return $asset_name;
 }
示例#14
0
 public function base58_encode($data, $littleEndian = true)
 {
     $res = '';
     $dataIntVal = gmp_init($data, 16);
     while (gmp_cmp($dataIntVal, gmp_init(0, 10)) > 0) {
         $qr = gmp_div_qr($dataIntVal, gmp_init(58, 10));
         $dataIntVal = $qr[0];
         $reminder = gmp_strval($qr[1]);
         if (!$this->base58_permutation($reminder)) {
             throw new \Exception('Something went wrong during base58 encoding');
         }
         $res .= $this->base58_permutation($reminder);
     }
     //get number of leading zeros
     $leading = '';
     $i = 0;
     while (substr($data, $i, 1) == '0') {
         if ($i != 0 && $i % 2) {
             $leading .= '1';
         }
         $i++;
     }
     if ($littleEndian) {
         return strrev($res . $leading);
     } else {
         return $res . $leading;
     }
 }
示例#15
0
 public function divide($y)
 {
     switch (MATH_BIGINTEGER_MODE) {
         case MATH_BIGINTEGER_MODE_GMP:
             $quotient = new Math_BigInteger();
             $remainder = new Math_BigInteger();
             list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
             if (gmp_sign($remainder->value) < 0) {
                 $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
             }
             return array($this->_normalize($quotient), $this->_normalize($remainder));
         case MATH_BIGINTEGER_MODE_BCMATH:
             $quotient = new Math_BigInteger();
             $remainder = new Math_BigInteger();
             $quotient->value = bcdiv($this->value, $y->value, 0);
             $remainder->value = bcmod($this->value, $y->value);
             if ($remainder->value[0] == '-') {
                 $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
             }
             return array($this->_normalize($quotient), $this->_normalize($remainder));
     }
     if (count($y->value) == 1) {
         list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
         $quotient = new Math_BigInteger();
         $remainder = new Math_BigInteger();
         $quotient->value = $q;
         $remainder->value = array($r);
         $quotient->is_negative = $this->is_negative != $y->is_negative;
         return array($this->_normalize($quotient), $this->_normalize($remainder));
     }
     static $zero;
     if (!isset($zero)) {
         $zero = new Math_BigInteger();
     }
     $x = $this->copy();
     $y = $y->copy();
     $x_sign = $x->is_negative;
     $y_sign = $y->is_negative;
     $x->is_negative = $y->is_negative = false;
     $diff = $x->compare($y);
     if (!$diff) {
         $temp = new Math_BigInteger();
         $temp->value = array(1);
         $temp->is_negative = $x_sign != $y_sign;
         return array($this->_normalize($temp), $this->_normalize(new Math_BigInteger()));
     }
     if ($diff < 0) {
         if ($x_sign) {
             $x = $y->subtract($x);
         }
         return array($this->_normalize(new Math_BigInteger()), $this->_normalize($x));
     }
     $msb = $y->value[count($y->value) - 1];
     for ($shift = 0; !($msb & MATH_BIGINTEGER_MSB); ++$shift) {
         $msb <<= 1;
     }
     $x->_lshift($shift);
     $y->_lshift($shift);
     $y_value =& $y->value;
     $x_max = count($x->value) - 1;
     $y_max = count($y->value) - 1;
     $quotient = new Math_BigInteger();
     $quotient_value =& $quotient->value;
     $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
     static $temp;
     static $lhs;
     static $rhs;
     if (!isset($temp)) {
         $temp = new Math_BigInteger();
         $lhs = new Math_BigInteger();
         $rhs = new Math_BigInteger();
     }
     $temp_value =& $temp->value;
     $rhs_value =& $rhs->value;
     $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
     while (0 <= $x->compare($temp)) {
         ++$quotient_value[$x_max - $y_max];
         $x = $x->subtract($temp);
         $x_max = count($x->value) - 1;
     }
     for ($i = $x_max; $y_max + 1 <= $i; --$i) {
         $x_value =& $x->value;
         $x_window = array(isset($x_value[$i]) ? $x_value[$i] : 0, isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0);
         $y_window = array($y_value[$y_max], 0 < $y_max ? $y_value[$y_max - 1] : 0);
         $q_index = $i - $y_max - 1;
         if ($x_window[0] == $y_window[0]) {
             $quotient_value[$q_index] = MATH_BIGINTEGER_MAX_DIGIT;
         } else {
             $quotient_value[$q_index] = (int) ($x_window[0] * MATH_BIGINTEGER_BASE_FULL + $x_window[1]) / $y_window[0];
         }
         $temp_value = array($y_window[1], $y_window[0]);
         $lhs->value = array($quotient_value[$q_index]);
         $lhs = $lhs->multiply($temp);
         $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
         while (0 < $lhs->compare($rhs)) {
             --$quotient_value[$q_index];
             $lhs->value = array($quotient_value[$q_index]);
             $lhs = $lhs->multiply($temp);
         }
         $adjust = $this->_array_repeat(0, $q_index);
         $temp_value = array($quotient_value[$q_index]);
         $temp = $temp->multiply($y);
         $temp_value =& $temp->value;
         $temp_value = array_merge($adjust, $temp_value);
         $x = $x->subtract($temp);
         if ($x->compare($zero) < 0) {
             $temp_value = array_merge($adjust, $y_value);
             $x = $x->add($temp);
             --$quotient_value[$q_index];
         }
         $x_max = count($x_value) - 1;
     }
     $x->_rshift($shift);
     $quotient->is_negative = $x_sign != $y_sign;
     if ($x_sign) {
         $y->_rshift($shift);
         $x = $y->subtract($x);
     }
     return array($this->_normalize($quotient), $this->_normalize($x));
 }
示例#16
0
 /**
  * Decode base58 into a PHP string.
  *
  * @param  string $base58 The base58 encoded string.
  * @since Release v1.1.0
  * @return string Returns the decoded string.
  */
 public function decode($base58)
 {
     // Type Validation
     if (is_string($base58) === false) {
         throw new InvalidArgumentException('Argument $base58 must be a string.');
     }
     // If the string is empty, then the decoded string is obviously empty
     if (strlen($base58) === 0) {
         return '';
     }
     $indexes = array_flip(str_split($this->alphabet));
     $chars = str_split($base58);
     // Check for invalid characters in the supplied base58 string
     foreach ($chars as $char) {
         if (isset($indexes[$char]) === false) {
             throw new InvalidArgumentException('Argument $base58 contains invalid characters.');
         }
     }
     // Convert from base58 to base10
     $decimal = gmp_init($indexes[$chars[0]], 10);
     for ($i = 1, $l = count($chars); $i < $l; $i++) {
         $decimal = gmp_mul($decimal, $this->base);
         $decimal = gmp_add($decimal, $indexes[$chars[$i]]);
     }
     // Convert from base10 to base256 (8-bit byte array)
     $output = '';
     while (gmp_cmp($decimal, 0) > 0) {
         list($decimal, $byte) = gmp_div_qr($decimal, 256);
         $output = pack('C', gmp_intval($byte)) . $output;
     }
     // Now we need to add leading zeros
     foreach ($chars as $char) {
         if ($indexes[$char] === 0) {
             $output = "" . $output;
             continue;
         }
         break;
     }
     return $output;
 }
示例#17
0
 /**
  * {@inheritdoc}
  */
 public function divQR($left, $right)
 {
     list($quotient, $remainder) = gmp_div_qr($left, $right);
     return [gmp_strval($quotient), gmp_strval($remainder)];
 }
示例#18
0
文件: deskripsi.php 项目: senusop/ci
    public function decript()
    {
        $this->load->view("fungsiRSA");
        /* 
        		-- keterangan Masing Masing Fungsi yang dipake dari Library gmp --
        gmp_div_qr = Bagi;
        		gmp_add    = Tambah;
        		gmp_mul    = Kali;
        		gmp_sub    = Kurang;
        		gmp_gcd    = Menghitung Nilai phi;
        		gmp_strval = Convert Nomer ke String;
        */
        // Inisialisasi P = 113 & Q = 157 (Masing Masing adalah Bilangan Prima) <--- Lebih Besar Lebih Bagus
        // Menghitung N = P*Q
        $n = gmp_mul(113, 157);
        $valn = gmp_strval($n);
        // Menghitung Nilai M =(p-1)*(q-1)
        $m = gmp_mul(gmp_sub(113, 1), gmp_sub(157, 1));
        // Mencari E (Kunci Public --> (e,n))
        // Inisialisasi E = 5
        // Membuktikan E = FPB (Faktor Persekutuan Terbesar) dari E dan M = 1
        for ($e = 5; $e < 1000; $e++) {
            // Mencoba dengan Perulangan 1000 Kali
            $fpb = gmp_gcd($e, $m);
            if (gmp_strval($fpb) == '1') {
                // Jika Benar E adalah FPB dari E dan M = 1 <-- Hentikan Proses
                break;
            }
        }
        // Menghitung D (Kunci Private --> (d,n))
        // D = (($m * $i) + 1) / e = $key[1] <-- Perulangan Do While
        $i = 1;
        do {
            $key = gmp_div_qr(gmp_add(gmp_mul($m, $i), 1), $e);
            $i++;
            if ($i == 1000) {
                // Dengan Perulangan 1000 Kali
                break;
            }
        } while (gmp_strval($key[1]) != '0');
        // Hasil D = $key[0]
        $d = $key[0];
        $vald = gmp_strval($d);
        $user = $this->input->post("user");
        $pesan = $this->input->post("pesan");
        if ($pesan != "") {
            $hasildekripsi = deskripsi($pesan, $d, $n);
            ?>
		
		<li class="left clearfix">
               
                <div class="chat-body clearfix">
                    <p class="bg-warning pesan">
                        <?php 
            echo $hasildekripsi[1];
            ?>
                    </p>
                </div>
            </li>
		
		<?php 
        } else {
            echo "<li class=\"right clearfix\">\r\n               \r\n                <div class=\"chat-body clearfix\">\r\n                    <p class=\"bg-warning pesan\">\r\n                        Belum ada data\r\n                    </p>\r\n                </div>\r\n            </li>";
        }
    }
示例#19
0
 /**
  * Creates an instance of {@code Duration} from a number of seconds.
  *
  * @param $nanos mixed the number of nanoseconds, positive or negative
  * @return Duration a {@code Duration}, not null
  * @throws ArithmeticException if numeric overflow occurs
  */
 private static function createBC($nanos)
 {
     $divRem = gmp_div_qr($nanos, LocalTime::NANOS_PER_SECOND);
     if (gmp_cmp($divRem[0], "-9223372036854775808") < 0 || gmp_cmp($divRem[0], "9223372036854775807") > 0) {
         throw new ArithmeticException("Exceeds capacity of Duration: " . gmp_strval($nanos));
     }
     return self::ofSeconds(gmp_intval($divRem[0]), gmp_intval($divRem[1]));
 }
示例#20
0
$com = gmp_com("1234");
echo gmp_strval($com) . "\n";
// gmp_div_q
$div1 = gmp_div_q("100", "5");
echo gmp_strval($div1) . "\n";
$div2 = gmp_div_q("1", "3");
echo gmp_strval($div2) . "\n";
$div3 = gmp_div_q("1", "3", GMP_ROUND_PLUSINF);
echo gmp_strval($div3) . "\n";
$div4 = gmp_div_q("-1", "4", GMP_ROUND_PLUSINF);
echo gmp_strval($div4) . "\n";
$div5 = gmp_div_q("-1", "4", GMP_ROUND_MINUSINF);
echo gmp_strval($div5) . "\n";
// gmp_div_qr
$a = gmp_init("0x41682179fbf5");
$res = gmp_div_qr($a, "0xDEFE75");
var_dump($res);
printf("Result is: q - %s, r - %s" . PHP_EOL, gmp_strval($res[0]), gmp_strval($res[1]));
// gmp_div_r
$div = gmp_div_r("105", "20");
echo gmp_strval($div) . "\n";
// gmp_div
$div1 = gmp_div("100", "5");
echo gmp_strval($div1) . "\n";
// gmp_divexact
$div1 = gmp_divexact("10", "2");
echo gmp_strval($div1) . "\n";
// gmp_fact
$fact1 = gmp_fact(5);
// 5 * 4 * 3 * 2 * 1
echo gmp_strval($fact1) . "\n";
示例#21
0
 /**
  * {@inheritdoc}
  */
 public function divide($amount, $divisor)
 {
     $divisor = Number::fromString((string) $divisor);
     if ($divisor->isDecimal()) {
         $decimalPlaces = strlen($divisor->getFractionalPart());
         if ($divisor->getIntegerPart()) {
             $divisor = Number::fromString($divisor->getIntegerPart() . $divisor->getFractionalPart());
         } else {
             $divisor = Number::fromString(ltrim($divisor->getFractionalPart(), '0'));
         }
         $amount = gmp_strval(gmp_mul(gmp_init($amount), gmp_init('1' . str_pad('', $decimalPlaces, '0'))));
     }
     list($integer, $remainder) = gmp_div_qr(gmp_init($amount), gmp_init((string) $divisor));
     if (gmp_cmp($remainder, '0') === 0) {
         return gmp_strval($integer);
     }
     $divisionOfRemainder = gmp_strval(gmp_div_q(gmp_mul($remainder, gmp_init('1' . str_pad('', $this->scale, '0'))), gmp_init((string) $divisor), GMP_ROUND_MINUSINF));
     return gmp_strval($integer) . '.' . str_pad($divisionOfRemainder, $this->scale, '0', STR_PAD_LEFT);
 }
示例#22
0
<?php

echo '10 + 0 = ', gmp_strval(gmp_add(10, 0)), "\n";
echo '10 + "0" = ', gmp_strval(gmp_add(10, '0')), "\n";
echo gmp_strval(gmp_div(10, 0)) . "\n";
echo gmp_strval(gmp_div_qr(10, 0)) . "\n";
示例#23
0
 /**
  * Base conversion. Bases 2..62 are supported
  *
  * @param  string $operand
  * @param  int    $fromBase
  * @param  int    $toBase
  * @return string
  * @throws Exception\InvalidArgumentException
  */
 public function baseConvert($operand, $fromBase, $toBase = 10)
 {
     if ($fromBase == $toBase) {
         return $operand;
     }
     if ($fromBase < 2 || $fromBase > 62) {
         throw new Exception\InvalidArgumentException("Unsupported base: {$fromBase}, should be 2..62");
     }
     if ($toBase < 2 || $toBase > 62) {
         throw new Exception\InvalidArgumentException("Unsupported base: {$toBase}, should be 2..62");
     }
     if ($fromBase <= 36 && $toBase <= 36) {
         return gmp_strval(gmp_init($operand, $fromBase), $toBase);
     }
     $sign = strpos($operand, '-') === 0 ? '-' : '';
     $operand = ltrim($operand, '-+');
     $chars = self::BASE62_ALPHABET;
     // convert operand to decimal
     if ($fromBase !== 10) {
         $decimal = '0';
         for ($i = 0, $len = strlen($operand); $i < $len; $i++) {
             $decimal = gmp_mul($decimal, $fromBase);
             $decimal = gmp_add($decimal, strpos($chars, $operand[$i]));
         }
     } else {
         $decimal = gmp_init($operand);
     }
     if ($toBase == 10) {
         return gmp_strval($decimal);
     }
     // convert decimal to base
     $result = '';
     do {
         list($decimal, $remainder) = gmp_div_qr($decimal, $toBase);
         $pos = gmp_strval($remainder);
         $result = $chars[$pos] . $result;
     } while (gmp_cmp($decimal, '0'));
     return $sign . $result;
 }
function gmp2bin($v)
{
    $binStr = '';
    while (gmp_cmp($v, 0) > 0) {
        list($v, $r) = gmp_div_qr($v, 256);
        $binStr = chr(gmp_intval($r)) . $binStr;
    }
    return $binStr;
}
示例#25
0
 /**
  * Read Windows FileTime and convert to Unix timestamp
  * Filetime = 64-bit value with the number of 100-nsec intervals since Jan 1, 1601 (UTC)
  * Based on http://www.mysqlperformanceblog.com/2007/03/27/integers-in-php-running-with-scissors-and-portability/
  * @return Unix timestamp, or -1 on error
  */
 private function readFiletime()
 {
     // Unix epoch (1970-01-01) - Windows epoch (1601-01-01) in 100ns units
     $EPOCHDIFF = '116444735995904000';
     $UINT32MAX = '4294967296';
     $USEC2SEC = 1000000;
     $lo = $this->readInt32();
     $hi = $this->readInt32();
     // check for 64-bit platform
     if (PHP_INT_SIZE >= 8) {
         // use native math
         if ($lo < 0) {
             $lo += 1 << 32;
         }
         $date = ($hi << 32) + $lo;
         $this->debugLog(sprintf('PAK CreationDate source: %016x', $date));
         if ($date == 0) {
             return -1;
         }
         // convert to Unix timestamp in usec
         $stamp = ($date - (int) $EPOCHDIFF) / 10;
         $this->debugLog(sprintf('PAK CreationDate 64-bit: %u.%06u', $stamp / $USEC2SEC, $stamp % $USEC2SEC));
         return (int) ($stamp / $USEC2SEC);
         // check for 32-bit platform
     } elseif (PHP_INT_SIZE >= 4) {
         $this->debugLog(sprintf('PAK CreationDate source: %08x%08x', $hi, $lo));
         if ($lo == 0 && $hi == 0) {
             return -1;
         }
         // workaround signed/unsigned braindamage on x32
         $lo = sprintf('%u', $lo);
         $hi = sprintf('%u', $hi);
         // try and use GMP
         if (function_exists('gmp_mul')) {
             $date = gmp_add(gmp_mul($hi, $UINT32MAX), $lo);
             // convert to Unix timestamp in usec
             $stamp = gmp_div(gmp_sub($date, $EPOCHDIFF), 10);
             $stamp = gmp_div_qr($stamp, $USEC2SEC);
             $this->debugLog(sprintf('PAK CreationDate GNU MP: %u.%06u', gmp_strval($stamp[0]), gmp_strval($stamp[1])));
             return (int) gmp_strval($stamp[0]);
         }
         // try and use BC Math
         if (function_exists('bcmul')) {
             $date = bcadd(bcmul($hi, $UINT32MAX), $lo);
             // convert to Unix timestamp in usec
             $stamp = bcdiv(bcsub($date, $EPOCHDIFF), 10, 0);
             $this->debugLog(sprintf('PAK CreationDate BCMath: %u.%06u', bcdiv($stamp, $USEC2SEC), bcmod($stamp, $USEC2SEC)));
             return (int) bcdiv($stamp, $USEC2SEC);
         }
         // compute everything manually
         $a = substr($hi, 0, -5);
         $b = substr($hi, -5);
         // hope that float precision is enough
         $ac = $a * 42949;
         $bd = $b * 67296;
         $adbc = $a * 67296 + $b * 42949;
         $r4 = substr($bd, -5) + substr($lo, -5);
         $r3 = substr($bd, 0, -5) + substr($adbc, -5) + substr($lo, 0, -5);
         $r2 = substr($adbc, 0, -5) + substr($ac, -5);
         $r1 = substr($ac, 0, -5);
         while ($r4 >= 100000) {
             $r4 -= 100000;
             $r3++;
         }
         while ($r3 >= 100000) {
             $r3 -= 100000;
             $r2++;
         }
         while ($r2 >= 100000) {
             $r2 -= 100000;
             $r1++;
         }
         $date = ltrim(sprintf('%d%05d%05d%05d', $r1, $r2, $r3, $r4), '0');
         // convert to Unix timestamp in usec
         $r3 = substr($date, -6) - substr($EPOCHDIFF, -6);
         $r2 = substr($date, -12, 6) - substr($EPOCHDIFF, -12, 6);
         $r1 = substr($date, -18, 6) - substr($EPOCHDIFF, -18, 6);
         if ($r3 < 0) {
             $r3 += 1000000;
             $r2--;
         }
         if ($r2 < 0) {
             $r2 += 1000000;
             $r1--;
         }
         $stamp = substr(sprintf('%d%06d%06d', $r1, $r2, $r3), 0, -1);
         $this->debugLog(sprintf('PAK CreationDate manual: %s.%s', substr($stamp, 0, -6), substr($stamp, -6)));
         return (int) substr($stamp, 0, -6);
     } else {
         return -1;
     }
 }
示例#26
0
文件: rsa.php 项目: senusop/ci
// Mencari E (Kunci Public --> (e,n))
// Inisialisasi E = 5
// Membuktikan E = FPB (Faktor Persekutuan Terbesar) dari E dan M = 1
for ($e = 5; $e < 1000; $e++) {
    // Mencoba dengan Perulangan 1000 Kali
    $fpb = gmp_gcd($e, $m);
    if (gmp_strval($fpb) == '1') {
        // Jika Benar E adalah FPB dari E dan M = 1 <-- Hentikan Proses
        break;
    }
}
// Menghitung D (Kunci Private --> (d,n))
// D = (($m * $i) + 1) / e = $key[1] <-- Perulangan Do While
$i = 1;
do {
    $key = gmp_div_qr(gmp_add(gmp_mul($m, $i), 1), $e);
    $i++;
    if ($i == 1000) {
        // Dengan Perulangan 1000 Kali
        break;
    }
} while (gmp_strval($key[1]) != '0');
// Hasil D = $key[0]
$d = $key[0];
$vald = gmp_strval($d);
// Jika Button Enkripsi ditekan
if (isset($_POST['enkrip']) && !empty($_POST['plain'])) {
    $plain = $_POST['plain'];
    $hasilenkripsi = enkripsi($plain, $n, $e);
} else {
    $hasilenkripsi = 'Ups, Sepertinya Plain Teks Masih Kosong';
示例#27
0
<?php

var_dump(gmp_div_qr());
var_dump(gmp_div_qr(""));
var_dump(gmp_div_qr(0, 1));
var_dump(gmp_div_qr(1, 0));
var_dump(gmp_div_qr(gmp_init(1), gmp_init(0)));
var_dump(gmp_div_qr(12653, 23482734));
var_dump(gmp_div_qr(12653, 23482734, 10));
var_dump(gmp_div_qr(1123123, 123));
var_dump(gmp_div_qr(1123123, 123, 1));
var_dump(gmp_div_qr(1123123, 123, 2));
var_dump(gmp_div_qr(gmp_init(1123123), gmp_init(123)));
var_dump(gmp_div_qr(1123123, 123, GMP_ROUND_ZERO));
var_dump(gmp_div_qr(1123123, 123, GMP_ROUND_PLUSINF));
var_dump(gmp_div_qr(1123123, 123, GMP_ROUND_MINUSINF));
$fp = fopen(__FILE__, 'r');
var_dump(gmp_div_qr($fp, $fp));
var_dump(gmp_div_qr(array(), array()));
echo "Done\n";
 public function toBinary()
 {
     $withZero = gmp_cmp($this->resource, 0);
     if ($withZero < 0) {
         throw new WrongArgumentException('only positive integers allowed');
     } elseif ($withZero === 0) {
         return "";
     }
     $bytes = array();
     $dividend = $this->resource;
     while (gmp_cmp($dividend, 0) > 0) {
         list($dividend, $reminder) = gmp_div_qr($dividend, 256);
         array_unshift($bytes, gmp_intval($reminder));
     }
     if ($bytes[0] > 127) {
         array_unshift($bytes, 0);
     }
     $binary = null;
     foreach ($bytes as $byte) {
         $binary .= pack('C', $byte);
     }
     return $binary;
 }
示例#29
0
 /**
  * Divides two BigIntegers.
  *
  * Returns an array whose first element contains the quotient and whose second element contains the
  * "common residue".  If the remainder would be positive, the "common residue" and the remainder are the
  * same.  If the remainder would be negative, the "common residue" is equal to the sum of the remainder
  * and the divisor (basically, the "common residue" is the first positive modulo).
  *
  * Here's an example:
  * <code>
  * <?php
  *    include 'Math/BigInteger.php';
  *
  *    $a = new Math_BigInteger('10');
  *    $b = new Math_BigInteger('20');
  *
  *    list($quotient, $remainder) = $a->divide($b);
  *
  *    echo $quotient->toString(); // outputs 0
  *    echo "\r\n";
  *    echo $remainder->toString(); // outputs 10
  * ?>
  * </code>
  *
  * @param Math_BigInteger $y
  * @return array
  * @access public
  * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
  */
 function divide($y)
 {
     switch (MATH_BIGINTEGER_MODE) {
         case MATH_BIGINTEGER_MODE_GMP:
             $quotient = new Math_BigInteger();
             $remainder = new Math_BigInteger();
             list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
             if (gmp_sign($remainder->value) < 0) {
                 $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
             }
             return array($this->_normalize($quotient), $this->_normalize($remainder));
         case MATH_BIGINTEGER_MODE_BCMATH:
             $quotient = new Math_BigInteger();
             $remainder = new Math_BigInteger();
             $quotient->value = bcdiv($this->value, $y->value, 0);
             $remainder->value = bcmod($this->value, $y->value);
             if ($remainder->value[0] == '-') {
                 $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
             }
             return array($this->_normalize($quotient), $this->_normalize($remainder));
     }
     if (count($y->value) == 1) {
         list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
         $quotient = new Math_BigInteger();
         $remainder = new Math_BigInteger();
         $quotient->value = $q;
         $remainder->value = array($r);
         $quotient->is_negative = $this->is_negative != $y->is_negative;
         return array($this->_normalize($quotient), $this->_normalize($remainder));
     }
     static $zero;
     if (!isset($zero)) {
         $zero = new Math_BigInteger();
     }
     $x = $this->copy();
     $y = $y->copy();
     $x_sign = $x->is_negative;
     $y_sign = $y->is_negative;
     $x->is_negative = $y->is_negative = false;
     $diff = $x->compare($y);
     if (!$diff) {
         $temp = new Math_BigInteger();
         $temp->value = array(1);
         $temp->is_negative = $x_sign != $y_sign;
         return array($this->_normalize($temp), $this->_normalize(new Math_BigInteger()));
     }
     if ($diff < 0) {
         // if $x is negative, "add" $y.
         if ($x_sign) {
             $x = $y->subtract($x);
         }
         return array($this->_normalize(new Math_BigInteger()), $this->_normalize($x));
     }
     // normalize $x and $y as described in HAC 14.23 / 14.24
     $msb = $y->value[count($y->value) - 1];
     for ($shift = 0; !($msb & MATH_BIGINTEGER_MSB); ++$shift) {
         $msb <<= 1;
     }
     $x->_lshift($shift);
     $y->_lshift($shift);
     $y_value =& $y->value;
     $x_max = count($x->value) - 1;
     $y_max = count($y->value) - 1;
     $quotient = new Math_BigInteger();
     $quotient_value =& $quotient->value;
     $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
     static $temp, $lhs, $rhs;
     if (!isset($temp)) {
         $temp = new Math_BigInteger();
         $lhs = new Math_BigInteger();
         $rhs = new Math_BigInteger();
     }
     $temp_value =& $temp->value;
     $rhs_value =& $rhs->value;
     // $temp = $y << ($x_max - $y_max-1) in base 2**26
     $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
     while ($x->compare($temp) >= 0) {
         // calculate the "common residue"
         ++$quotient_value[$x_max - $y_max];
         $x = $x->subtract($temp);
         $x_max = count($x->value) - 1;
     }
     for ($i = $x_max; $i >= $y_max + 1; --$i) {
         $x_value =& $x->value;
         $x_window = array(isset($x_value[$i]) ? $x_value[$i] : 0, isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0);
         $y_window = array($y_value[$y_max], $y_max > 0 ? $y_value[$y_max - 1] : 0);
         $q_index = $i - $y_max - 1;
         if ($x_window[0] == $y_window[0]) {
             $quotient_value[$q_index] = MATH_BIGINTEGER_MAX_DIGIT;
         } else {
             $quotient_value[$q_index] = $this->_safe_divide($x_window[0] * MATH_BIGINTEGER_BASE_FULL + $x_window[1], $y_window[0]);
         }
         $temp_value = array($y_window[1], $y_window[0]);
         $lhs->value = array($quotient_value[$q_index]);
         $lhs = $lhs->multiply($temp);
         $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
         while ($lhs->compare($rhs) > 0) {
             --$quotient_value[$q_index];
             $lhs->value = array($quotient_value[$q_index]);
             $lhs = $lhs->multiply($temp);
         }
         $adjust = $this->_array_repeat(0, $q_index);
         $temp_value = array($quotient_value[$q_index]);
         $temp = $temp->multiply($y);
         $temp_value =& $temp->value;
         $temp_value = array_merge($adjust, $temp_value);
         $x = $x->subtract($temp);
         if ($x->compare($zero) < 0) {
             $temp_value = array_merge($adjust, $y_value);
             $x = $x->add($temp);
             --$quotient_value[$q_index];
         }
         $x_max = count($x_value) - 1;
     }
     // unnormalize the remainder
     $x->_rshift($shift);
     $quotient->is_negative = $x_sign != $y_sign;
     // calculate the "common residue", if appropriate
     if ($x_sign) {
         $y->_rshift($shift);
         $x = $y->subtract($x);
     }
     return array($this->_normalize($quotient), $this->_normalize($x));
 }
 public static function asset_name(GMP $asset_id)
 {
     if (gmp_cmp($asset_id, 0) === 0) {
         return 'BTC';
     }
     if (gmp_cmp($asset_id, 1) === 0) {
         return 'XCP';
     }
     $b26_digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
     if ($asset_id < pow(26, 3)) {
         throw new Exception("asset ID was too low", 1);
     }
     // look for numeric asset name
     if (gmp_cmp($asset_id, gmp_add(gmp_pow(26, 12), 1)) >= 0) {
         return 'A' . $asset_id;
     }
     # Divide that integer into Base 26 string.
     $asset_name = '';
     $n = clone $asset_id;
     while (gmp_cmp($n, 0) > 0) {
         list($n, $r) = gmp_div_qr($n, 26, GMP_ROUND_ZERO);
         $asset_name = substr($b26_digits, gmp_intval($r), 1) . $asset_name;
     }
     return $asset_name;
 }