bcpowmod

(PHP 5, PHP 7)

bcpowmod임의 정밀도 수를 거듭제곱하고, 지정한 제수로 나머지를 구합니다

설명

string bcpowmod ( string $left_operand , string $right_operand , string $modulus [, int $scale ] )

left_operandright_operand승에 대한 modulus의 나머지를 구하기 위한 빠른 누승법을 사용합니다.

인수

left_operand

왼쪽 연산수, 문자열.

right_operand

오른쪽 연산수, 문자열.

modulus

제수, 문자열.

scale

이 선택적인 인수는 소수점 아래 자리수를 설정합니다. bcscale()을 사용하여 모든 함수에 대한 전역 기본값을 설정할 수 있습니다.

반환값

결과를 문자열로 반환하거나, modulus가 0이면 NULL을 반환합니다.

주의

Note:

이 방법은 나머지 연산을 사용하기에, 자연수가 아닌 수는 예측할 수 없는 결과를 가져옵니다. 자연수는 0이 아닌 양의 정수입니다.

예제

다음 두 구문은 기능상 동일합니다. 그러나 bcpowmod() 버전이 짧은 시간에 수행되고 더 큰 인수를 허용합니다.

<?php
$a 
bcpowmod($x$y$mod);

$b bcmod(bcpow($x$y), $mod);

// $a와 $b는 동일합니다.

?>

참고

  • bcpow() - 임의 정밀도 수 거듭제곱
  • bcmod() - 임의 정밀도 수의 나머지를 구합니다

add a note add a note

User Contributed Notes 3 notes

up
2
ewilde aht bsmdevelopment dawt com
19 years ago
Versions of PHP prior to 5 do not have bcpowmod in their repertoire.  This routine simulates this function using bcdiv, bcmod and bcmul.  It is useful to have bcpowmod available because it is commonly used to implement the RSA algorithm.

The function bcpowmod(v, e, m) is supposedly equivalent to bcmod(bcpow(v, e), m).  However, for the large numbers used as keys in the RSA algorithm, the bcpow function generates a number so big as to overflow it.  For any exponent greater than a few tens of thousands, bcpow overflows and returns 1.

This routine will iterate through a loop squaring the result, modulo the modulus, for every one-bit in the exponent.  The exponent is shifted right by one bit for each iteration.  When it has been reduced to zero, the calculation ends.

This method may be slower than bcpowmod but at least it works.

function PowModSim($Value, $Exponent, $Modulus)
  {
  // Check if simulation is even necessary.
  if (function_exists("bcpowmod"))
    return (bcpowmod($Value, $Exponent, $Modulus));

  // Loop until the exponent is reduced to zero.
  $Result = "1";

  while (TRUE)
    {
    if (bcmod($Exponent, 2) == "1")
      $Result = bcmod(bcmul($Result, $Value), $Modulus);

    if (($Exponent = bcdiv($Exponent, 2)) == "0") break;

    $Value = bcmod(bcmul($Value, $Value), $Modulus);
    }

  return ($Result);
  }
up
-3
rrasss at gmail dot com
18 years ago
However, if you read his full note, you see this paragraph:
"The function bcpowmod(v, e, m) is supposedly equivalent to bcmod(bcpow(v, e), m).  However, for the large numbers used as keys in the RSA algorithm, the bcpow function generates a number so big as to overflow it.  For any exponent greater than a few tens of thousands, bcpow overflows and returns 1."

So you still can, and should (over bcmod(bcpow(v, e), m) ), use his function if you are using larger exponents, "any exponent greater than a few tens of thousand."
up
-5
laysoft at gmail dot com
17 years ago
I found a better way to emulate bcpowmod on PHP 4, which works with very big numbers too:

function powmod($m,$e,$n) {
    if (intval(PHP_VERSION)>4) {
        return(bcpowmod($m,$e,$n));
    } else {
        $r="";
        while ($e!="0") {
            $t=bcmod($e,"4096");
            $r=substr("000000000000".decbin(intval($t)),-12).$r;
            $e=bcdiv($e,"4096");
        }
        $r=preg_replace("!^0+!","",$r);
        if ($r=="") $r="0";
        $m=bcmod($m,$n);
        $erb=strrev($r);
        $q="1";
        $a[0]=$m;
        for ($i=1;$i<strlen($erb);$i++) {
            $a[$i]=bcmod(bcmul($a[$i-1],$a[$i-1]),$n);
        }
        for ($i=0;$i<strlen($erb);$i++) {
            if ($erb[$i]=="1") {
                $q=bcmod(bcmul($q,$a[$i]),$n);
            }
        }
        return($q);
    }
}
To Top