Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a cryptographically strong integer from 0-X in PHP?

Tags:

php

random

I want to generate random alphanumeric strings in PHP. They will be used in places where the strength of random numbers is important (publicly visible IDs in URLs and the like).

As I understand, in PHP the main source of cryptographically strong randomness is openssl_random_pseudo_bytes(). This however returns an array of bytes, not alphanumeric characters.

To convert them to alphanumerics I could either hash them (which would produce a longer-than-necessary string of a limited set of hex characters), or base64_encode() them (which would produce a string with +, / and = in it - not alphanumerics).

So I think that instead I could use the random bytes as a source of entropy and generated my own string consisting only of the characters 0-9a-zA-Z.

The problem then becomes - how to translate from 256 distinct values (one byte of input) to 62 distinct value (one character of output). And in a way, that all 62 characters are equally as likely. (Otherwise there will be 8 characters that appear more often than the rest).

Or perhaps I should use another approach entirely? I would like my string to be as short as possible (say, 20 characters or so - shorter URLs are better) and consist only of alphanumeric characters (so that it doesn't need to be specially escaped anywhere).

like image 744
Vilx- Avatar asked Nov 01 '13 17:11

Vilx-


People also ask

How do I check if a PHP function is cryptographically strong?

PHP will try to cast this parameter to a non-null integer to use it. If passed into the function, this will hold a bool value that determines if the algorithm used was "cryptographically strong", e.g., safe for usage with GPG, passwords, etc. true if it did, otherwise false Returns the generated string of bytes on success, or false on failure.

How do I get a cryptographically strong random value?

The Crypto.getRandomValues () method lets you get cryptographically strong random values. The array given as the parameter is filled with random numbers (random in its cryptographic meaning).

How do I generate random integers or strings in PHP?

Quick Answer: If you're developing a web application and your project needs a simple and safe solution for generating random integers or strings, just use random_bytes() (PHP 7 only, or available through our random_compat library).

What is the most important feature of PHP?

This generator is the most important and helpful feature of PHP. All generators which we will discuss above are not cryptographically secure. Cryptographically secure means it can also generate a random string, but it is hard for a third party to generate the same random number. That’s why we can say it cryptographically secure.


1 Answers

You can implement your own base64 encoding, sort of. If you can allow two specific symbols - these can be anything, for example . and -, it doesn't really matter. It can even be a space for one of them. In any case, what you would do is this:

$alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-";
// using . and - for the two symbols here
$input = [123,193,21,13]; // whatever your input it, I'm assuming an array of bytes
$output = "";
foreach($input as $byte) {
    $output .= $alphabet[$byte%64];
}

Assuming random input, all characters have equal probability of appearing.

That being said, if you can't allow anything except pure alphanumeric, cut the symbols from the $alphabet and use %62 instead of %64. While this does mean you have a small bias towards the chracters 0 through 7, I don't think it's significant enough to worry about.

like image 161
Niet the Dark Absol Avatar answered Nov 08 '22 05:11

Niet the Dark Absol