zend.math.introduction.md 5.91 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
# Introduction to Zend\\Math

`Zend\Math` namespace provides general mathematical functions. So far the supported functionalities
are:

* `Zend\Math\Rand`, a random number generator;
* `Zend\Math\BigInteger`, a library to manage big integers.

We expect to add more functionalities in the future.

## Random number generator

`Zend\Math\Rand` implements a random number generator that is able to generate random numbers for
general purpose usage and for cryptographic scopes. To generate good random numbers this component
uses different approaches. If PHP 7 is running we used the cryptographically secure pseudo-random
functions [random_bytes](http://php.net/manual/en/function.random-bytes.php) and
[random_int](http://php.net/manual/en/function.random-int.php), otherwise we use the
[Mcrypt](http://it.php.net/manual/en/book.mcrypt.php) extension or /dev/urandom source.
If you don't have a secure random source in your environment the component
will use the library [ircmaxell/RandomLib](https://github.com/ircmaxell/RandomLib) with a
medium strength generator.

The `Zend\Math\Rand` class offers the following methods to generate random values:

* `getBytes($length, $strong = false)` to generate a random set of `$length` bytes;
* `getBoolean($strong = false)` to generate a random boolean value (true or false);
* `getInteger($min, $max, $strong = false)` to generate a random integer between `$min` and `$max`;
* `getFloat($strong = false)` to generate a random float number between 0 and 1;
* `getString($length, $charlist = null, $strong = false)` to generate a random string of $length
characters using the alphabet $charlist (if not provided the default alphabet is the
[Base64](http://en.wikipedia.org/wiki/Base64)).

In all these methods the parameter `$strong` specify the usage of a strong random number generator.
We suggest to set the $strong to true if you need to generate random number for cryptographic and
security implementation.

If `$strong` is set to true and you try to generate random values in a PHP environment without a
secure pseudo-random source the component will throw an Exception.

Below we reported an example on how to generate random data using `Zend\Math\Rand`.

```php
use Zend\Math\Rand;

$bytes = Rand::getBytes(32, true);
printf("Random bytes (in Base64): %s\n", base64_encode($bytes));

$boolean = Rand::getBoolean();
printf("Random boolean: %s\n", $boolean ? 'true' : 'false');

$integer = Rand::getInteger(0,1000);
printf("Random integer in [0-1000]: %d\n", $integer);

$float = Rand::getFloat();
printf("Random float in [0-1): %f\n", $float);

$string = Rand::getString(32, 'abcdefghijklmnopqrstuvwxyz', true);
printf("Random string in latin alphabet: %s\n", $string);
```

## Big integers

`Zend\Math\BigInteger\BigInteger` offers a class to manage arbitrary length integer. PHP supports
integer numbers with a maximum value of `PHP_INT_MAX`. If you need to manage integers bigger than
`PHP_INT_MAX` you have to use external libraries or PHP extensions like
[GMP](http://www.php.net/manual/en/book.gmp.php) or [BC
Math](http://www.php.net/manual/en/book.bc.php).

`Zend\Math\BigInteger\BigInteger` is able to manage big integers using the GMP or the BC Math
extensions as adapters.

The mathematical functions implemented in `Zend\Math\BigInteger\BigInteger` are:

* `add($leftOperand, $rightOperand)`, add two big integers;
* `sub($leftOperand, $rightOperand)`, subtract two big integers;
* `mul($leftOperand, $rightOperand)`, multiply two big integers;
* `div($leftOperand, $rightOperand)`, divide two big integers (this method returns only integer part
of result);
* `pow($operand, $exp)`, raise a big integers to another;
* `sqrt($operand)`, get the square root of a big integer;
* `abs($operand)`, get the absolute value of a big integer;
* `mod($leftOperand, $modulus)`, get modulus of a big integer;
* `powmod($leftOperand, $rightOperand, $modulus)`, raise a big integer to another, reduced by a
specified modulus;
* `comp($leftOperand, $rightOperand)`, compare two big integers, returns < 0 if leftOperand is
less than rightOperand; > 0 if leftOperand is greater than rightOperand, and 0 if they are equal;
* `intToBin($int, $twoc = false)`, convert big integer into it's binary number representation;
* `binToInt($bytes, $twoc = false)`, convert binary number into big integer;
* `baseConvert($operand, $fromBase, $toBase = 10)`, convert a number between arbitrary bases;

Below is reported an example using the BC Math adapter to calculate the sum of two integer random
numbers with 100 digits.

```php
use Zend\Math\BigInteger\BigInteger;
use Zend\Math\Rand;

$bigInt = BigInteger::factory('bcmath');

$x = Rand::getString(100,'0123456789');
$y = Rand::getString(100,'0123456789');

$sum = $bigInt->add($x, $y);
$len = strlen($sum);

printf("%{$len}s +\n%{$len}s =\n%s\n%s\n", $x, $y, str_repeat('-', $len), $sum);
```

As you can see in the code the big integers are managed using strings. Even the result of the sum is
represented as a string.

Below is reported another example using the BC Math adapter to generate the binary representation of
a negative big integer of 100 digits.

```php
use Zend\Math\BigInteger\BigInteger;
use Zend\Math\Rand;

$bigInt = BigInteger::factory('bcmath');

$digit = 100;
$x = '-' . Rand::getString($digit,'0123456789');

$byte = $bigInt->intToBin($x);

printf("The binary representation of the big integer with $digit digit:\n%s\nis (in Base64 format):
%s\n",
       $x, base64_encode($byte));
printf("Length in bytes: %d\n", strlen($byte));

$byte = $bigInt->intToBin($x, true);

printf("The two's complement binary representation of the big integer with $digit digit:\n%s\nis (in
Base64 format): %s\n",
       $x, base64_encode($byte));
printf("Length in bytes: %d\n", strlen($byte));
```

We generated the binary representation of the big integer number using the default binary format and
the [two's complement](http://en.wikipedia.org/wiki/Two%27s_complement) representation (specified
with the `true` parameter in the `intToBin` function).