I have a form that inserts items into a MySQL database upon submission. I have decided to create 16 bit IDs for the items using the random_bytes
method in PHP so that every time the form submits I already know the ID and don't have to re-query the database for it for it.
In order to insert the ID into a link in the page I have tried using the bin2hex
method. This normally works correctly. However, when the ID has trailing zeros the method seems to cut them off (passing in the direct result of the random_bytes
method). In other pages where I use the function on the same ID retrieved from the database it does not do this and works correctly.
In other words, if the ID ends in 000, it is shown correctly in the hexadecimal representation when bin2hex
is called on the database retrieved binary representation. However, the zeros are missing in the hexadecimal representation when the function is called on the direct output of the random_bytes
function.
Here is the initial code:
$uuid = random_bytes(16);
$uuidHex = bin2hex($uuid);
Later in the same script:
$GLOBALS["ID"] = '0x' . $uuidHex;
Script inside link href
attribute:
<?php echo $ID; ?>
Here is an example ID where the problem would occur:
0xa87ea4fc142fcdeasjf90j3771eda500
How do we ever know that bin2hex
is cutting of trailing zeros?
$uuid = random_bytes(16);
This is unreadable, this will give you cryptographically strong random bytes. We convert it to hexadecimal.
$uuidHex = bin2hex($uuid);
Now this will give you a random string of 32 bits not 16. But why? Because, in hex, a byte is always expressed as 2 characters. Divide 32 by 2. Also, you are adding "'0x'" to in the string which will make it 18 bit. To get a resultant of 16 bits, Do this
$uuid = random_bytes(7);
$uuidHex = bin2hex($uuid);
$GLOBALS["ID"] = '0x' . $uuidHex; // 16 bit string
Because with random_bytes(7)
we are getting 7 times 2 of string length which is 14 and then we append "0x" which makes is 14 + 2
=
a 16
bit string