I'm creating a security system in PHP which requires the user to enter a certain character from their unique security key, I was wondering how it is possible to make php return a selected character from a string.
For example, the security code is 1234567, I want php to randomly select 1 character from this string, and then compare that character to the character asked for in the security process
$number = rand(1,7);
// The number = 7
E.G, please enter the 7th character of your security code.
//script to return the 7th character in the string and compare it to the entered character.
Thanks in advance :)
$randomIndex = mt_rand(0, strlen($securityCode) - 1);
$randomChar = $securityCode[$randomIndex];
This creates a random number (mt_rand) between 0 and the last index of your string (strlen($securityCode) - 1). If your string is 10 characters long, that's a number between 0 and 9. It then takes the character at that index.
Try substr, strlen and rand
$numbers = rand(0,strlen($securitycode) - 1);
$randChar = substr($securitycode, $numbers, 1);
Then compare..
Related
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).
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.
I found this function on php.net in the user comments.
function crypto_rand($min,$max) {
$range = $max - $min;
if ($range == 0) return $min; // not so random...
$length = (int) (log($range,2) / 8) + 1;
return $min + (hexdec(bin2hex(openssl_random_pseudo_bytes($length,$s))) % $range);
}
Then do something like
for($i=0; $i<20; $i++)
{
$string.= chr(crypto_rand(1,26)+96); //or +64 for upper case
}
Or similar.
note: THIS IS WRONG! I leave this attempted answer for reference only.
(31 * 256) % 62 = 0
For each output alphanumeric character, generate 31 random values. Sum these 31 values and take the modulo 62.
Kind of brutal, but this is the only "mathematicaly correct" option I can think of :)
A simple problem.
I have the following string "48063974806397"
You will notice that this is just "4806397" repeated twice.
I need a way to recognize the repeat point, and just get the first instance of the pattern. E.g final return should just be "4806397".
(The length of the first number will not always be the same.)
I wanted to return this a variable in php.
How could I do this?
Thanks
If it's always just a string duplicated twice, then it's as simple as just taking the first half of the string:
$halfstring = substr($string, 0, strlen($string) / 2);
Use strlen() to get the length of the string, and divide that by 2. Then use substr() to just get the first half.
If that's always a number, math helps:
$halfStr = $n / (pow(10, strlen($n) / 2) + 1);
I want to generate a random password of 15 characters that contains BOTH numbers and letters. Is there a simple way to do this?
I want to avoid a situation where I get all numbers in the password, but do not want to prefix the password with any letters.
Generate an array with a random number, a random character and 13 random chars/numbers and then use shuffle
You could use:
$pw = substr(md5(uniqid()), 0, 15);
I think it's very unlikely to end up with all numbers with this approach.
you can generate the password in a loop till the length of password string you want. You can use rand() function within it to avoid the continues characters you can also use ASCII code for it with char() function
How about this? Generates a highly random alphanumeric password of 15 chars.
$p = substr ( md5(uniqid(rand(), true)), 0, 15);
Users will be filling a field in with numbers relating to their account. Unfortunately, some users will have zeroes prefixed to the beginning of the number to make up a six digit number (e.g. 000123, 001234) and others won't (e.g. 123, 1234). I want to 'trim' the numbers from users that have been prefixed with zeros in front so if a user enters 000123, it will remove the zeroes to become 123.
I've had a look at trim and substr but I don't believe these will do the job?
You can use ltrim() and pass the characters that should be removed as second parameter:
$input = ltrim($input, '0');
// 000123 -> 123
ltrim only removes the specified characters (default white space) from the beginning (left side) of the string.
ltrim($usernumber, "0");
should do the job, according to the PHP Manual
$number = "004561";
$number = intval($number, 10);
$number = (string)$number; // if you want it to again be a string
You can always force PHP to parse this as an int. If you need to, you can convert it back to a string later
(int) "000123"
You can drop the leading zeros by converting from a string to a number and back again. For example:
$str = '000006767';
echo ''.+$str; // echo "6767"
Just multiply your number by zero.
$input=$input*1;
//000000123*1 = 123
I have 62 base64 characters that I want to randomize. How can I do this using PHP? The string would be all letters, upper and lower case as well as numbers from 0-9.
The thing that is most important to me is that the entire string be evaluated before a return value is given. In other words, if I request a string of 8 characters in length and my string starts out like:
1234567890ABCDE..... I don't want to get the first 8 numbers randomized. It should randomize the entire string first, then return 8 characters from that.
Try this:
$string = '1234567890ABCDE...';
$string = substr(str_shuffle($string), 0, 8);
str_shuffle randomizes the string, then substr takes the first 8 characters from it.
Take a look at str_shuffle.