I'm trying to generate a number from 0 to 36 in php that can be proven that it was fair later.
I've had a google around and found a formula that works, however I'm having a bit of trouble getting it to work in PHP.
roll_hash = hash("sha256", server_seed + "-" + lottery + "-" + roll_id);
roll_hash_first16 = substr(roll_hash, 0, 16);
roll_lucky_number = hex_to_uint64(roll_hash_first16) % 15;
is the formula I've found, however I can't get it to work in PHP.
This is the PHP code I've tried however it doesn't do what I need it to do.
$server_seed = "577701c29f6e4a409b8a607cb95c79c943146dc7dff3eb6894a34837076e7365";
$salt = "fe5e5c41b";
$roll_id = 0;
$roll_hash = hash("sha256", $server_seed + "-" + $salt + "-" + $roll_id);
$roll_hash_first16 = substr($roll_hash, 0, 36);
$roll_lucky_number = hexdec($roll_hash_first16) / 35;
This code will just generate something like "5.3687216943283E+41"
I need it to generate a plain number from 0 to 36 and which should be the same whenever the server seed, salt and roll_id are the same.
Here's the corrected version of the PHP code though:
function generateRandomNumber(string $seed, string $salt, int $roll): int
{
$roll_hash = hash("sha256", $seed . "-" . $salt . "-" . $roll);
$roll_hash_first16 = substr($roll_hash, 0, 16);
return abs(hexdec($roll_hash_first16) % 37);
}
https://3v4l.org/QMgNR
Related
I'm trying to implement my own PHP function to generate codes for Google Authenticator. I do it for fun and to learn something new. Here's what I did:
function twoFactorAuthorizationCode(string $secretBase32, int $digitsCount): string {
$counter = (int) (time() / 30);
$secret = Base32::decode($secretBase32);
$hash = hash_hmac('sha1', $counter, $secret, true); // 20 binary characters
$hexHash = unpack('H*', $hash)[1]; // 40 hex characters
$offset = hexdec($hexHash[-1]); // last 4 bits of $hash
$truncatedHash = hexdec(substr($hexHash, $offset * 2, 8)) & 0x7fffffff; // last 31 bits
$code = $truncatedHash % (10 ** $digitsCount);
return str_pad($code, $digitsCount, '0', STR_PAD_LEFT);
}
I'm not sure which step is wrong, but it doesn't generate the same results as Google Authenticator. Obviously, I tried to play with time offsets in case my clock is not in sync with Google Authenticator's.
Some of the things I'm not sure are:
Should the secret be decoded from Base32, or should it stay the Base32 string?
Is the counter a value or a key for SHA1 hash?
I did a lot of experiments and I can't get my algorithm to generate a valid result. Any advice is highly appreciated.
I have found the answer by trials and errors. So, the problem was in the $counter value that I've been hashing directly:
$hash = hash_hmac('sha1', $counter, $secret, true);
Instead, it should be a 64-bit binary string made from the $counter:
$packedCounter = pack('J', $counter);
$hash = hash_hmac('sha1', $packedCounter, $secret, true);
Explanation
Let's say our Unix timestamp is 1578977176.
That makes the counter as follows: (int) (1578977176 / 30) = 52632572.
The value used for hashing needs to be a 64-bit, big endian byte order string. It means that we need to left-pad it with zeros to make it 64-bit.
52632572 is 11001000110001101111111100 in binary. That's just 26 bits, so we need 38 more. What we have now is:
0000000000000000000000000000000000000011001000110001101111100010.
Every character is one byte, so we split it into the groups of 8:
00000000 00000000 00000000 00000000 00000011 00100011 00011011 11100010
We can now convert every group to a character by its code:
$packedCounter = chr(0b00000000)
. chr(0b00000000)
. chr(0b00000000)
. chr(0b00000000)
. chr(0b00000011)
. chr(0b00100011)
. chr(0b00011011)
. chr(0b11100010);
And that's the string we want to hash, which is exactly what pack('J', $string) does.
VoilĂ !
I'm creating player panel for my friend in php, but I have problem with variable shown below. I must insert into variable in php, and send request to database. What is my problem? I can't convert java code, because I don't know how I can do this. It may be strange, but unfortunately it is.
I tried do this with amateur way, using;
require 'mojang-api.class.php';
$uuid = MojangAPI::getUuid('jeb_');
echo 'UUID: <b>' . $uuid . '</b><br>';
echo substr($uuid, 0, 8); echo '-'; echo substr($uuid, 8, 12); echo '-'; substr($uuid, 13, 15); echo '-';
but, You and I know this - this way sucks.
I place the java code below.
Java:
uuid.substring(0, 8) + '-' + uuid.substring(8, 12) + '-' + uuid.substring(12, 16) + '-' + uuid.substring(16, 20) + '-' + uuid.substring(20)
If someone can help me with this problem, I'll be grateful.
Is this what you are looking for
$uuid = MojangAPI::getUuid('jeb_');
echo 'UUID: <b>' . $uuid . '</b><br>';
echo substr($uuid, 0, 8).'-'.substr($uuid, 8, 4).'-'.substr($uuid, 13, 2);
Instead of plus + in Java you use the dot . in PHP. Amazingly you used it in the line above?
Hi everyone i really need help with my final coding for my Generator.
TO DO :
There need to be some reverse way of doing this :
8 length generated code
0000 0000 = Code Number 0
0000 0001 = Code Number 1
0000 0158 = Code Number (1 * 10^2) + (5 * 10^1) + (8 * 10^0) = 158
For Alphabets (A=0, B=1, C= 2, ... Z = 25, a = 26, ..., z = 51, 0 = 52, 1 = 53, 9 = 61:
AAAA ABCD = Code Number (0 * 62^7) + (0 * 62^6) + (0 * 62^5) + (0 + 62^4) + (0 * 62^3) + (1 * 62^2) + (2 * 62^1) + (3 * 62^0) = 14780307
This is the current way :
generate key -> count the possicion of the key
Solution wanted :
input ID -> generate key without too much cycling by PHP "for" cycle
At the moment if i input ID 5,000,000 with proper setting the script hang up or the page will become unavailable.
I haven't found any simple solution of how to reverse it,but i believe there must be somethnig to solve this issue.
So if anyone know a solution please feel free to develop and commit.
Thanks
Click here to see the BaseCode
I've found similar solution here at github and after understanding the code i have created working PHP example :
// Digital number -->> AlphaNum code
$code_id = 1;
$code_length = 8;
$characters_range = array_merge(range('A','Z'), range(0,9));
$characters_count = count($characters_range);
$code_max_id = bcpow($characters_count, $code_length);
echo $code_max_id;
echo "\n";
for($length=($code_length-1);$length>=0;$length--){
$possition = floor($code_id / bcpow($characters_count, $length));
$code_id = $code_id - ($possition * bcpow($characters_count, $length));
$character_keys[] = $characters_range[$possition];
}
//Choose which one to use
//echo implode($character_keys);
print_r($character_keys);
Here is a Czech website with the same thread.
So now i can finalise my CANG("Complex Alpha-Numeric Generator") without any trouble.
In an incoming UDP packet I have the hex value b70500. This is actually a sequence number (1463). I need to increment this value before sending it back to the server in the same format (b80500).
How can I, in PHP, increment the value by one?
Using the code suggested here I was able to convert the hex value to an integer and increment it by one:
$original_hex = 'b70500'; // 1463
$original_int = unpack("H*", strrev(pack("H*", $original_hex))); // 0005b7
$incremented_int = hexdec($original_int[1]) + 1; // 1464
$incremented_hex = ? // Expected result: b80500
... But I have no idea how to convert it back into hex. Perhaps there is a more efficient method?
hexdec() and dechex(). You do not have to unpack the value.
$incremented = dechex(hexdec('b70500') + 1);
It's not pretty and I bet there are more efficient ways of doing this, but it works:
function increment_hex($hex) {
$original_hex = $hex;
$original_int = unpack("H*", strrev(pack("H*", $original_hex)));
$incremented_int = hexdec($original_int[1]) + 1;
$incremented_hex = dechex($incremented_int);
$padded_hex = str_pad($incremented_hex, 6, '0', STR_PAD_LEFT);
$reversed_hex = unpack("H*", strrev(pack("H*", $padded_hex)));
return $reversed_hex[1];
}
echo "result: " . increment_hex('b70500') . "\n";
result: b80500
I am trying to list the current USD price of an item in mBTC (millibitcoin) using the Coinbase API. Here is my code:
<?php
$string = file_get_contents('https://coinbase.com/api/v1/prices/spot_rate');
$result = json_decode($string);
$spot = $result->amount;
$price = 2; //change this to your USD value
$whole = substr($price/$spot, 4, -13);
$dec = substr($price/$spot, 4, -12);
echo $whole.'.'.$dec.' mBTC';
?>
It works flawlessly in Coderunner (OS X app for development) but fails when run on my hosting server. Link to browser script: http://bitcoindecals.com/oval-price.php
I am using Dynadot Advanced hosting and it includes PHP support. I know that PHP is being utilized because "mBTC" is being echoed correctly. It just appears the $whole and $dec variables aren't being set for some reason. Is there a way to get this to work?
You're making a few (extremly wrong) assumptions in the following lines:
$whole = substr($price/$spot, 4, -13);
$dec = substr($price/$spot, 4, -12);
$price / $spot is treated as a string and you assume it will be in the format
'0.0019XXXXXXXXXXXX' // 12 x's (unkown numbers)
What if Bitcoin is doing really bad and the rate exeeds 10 mBTC per USD? $price / $spot will be something like:
'0.0108491827849201'; // (10.8 mBTC)
$whole = substr('0.0108491827849201', 4, -13); // Will be '0'
$dec = substr('0.0108491827849201', 4, -12); // Will be '08'
echo $whole . '.' . $dec . ' mBTC'; // Will echo '0.08 mBTC'
What if, due to rounding or accuracy (! this is what you're seeing in your server - most likely because your OSX is 64bit, your server 32bit or vice-versa !), the string-length of $price / $spot is less than 18 characters:
'0.0019564521431';
$whole = substr('0.0019564521431', 4, -13);
// Meaning: start at position 4, stop at 13 characters counting from the end
// 13 characters from the end is here: '0.0019564521431'
// ^
// so the stop-position is before the start-position, resulting in an empty
// string. Same with $dec.
echo $whole . '.' . $dec . ' mBTC';
// Will echo empty-string . '.' . empty-string . ' mBTC': '. mBTC'
Long story short: never ever treat numbers as a string (unless you have no other options and you are fully aware of what you are doing). Following code will work, and will give the correct output:
echo number_format($price / $spot * 1000, 1);
// multiply by 1000: BTC to milli-BTC
// , 1: One digit after the dot
For a full explanation of number_format see: http://php.net/number_format
I just executed the exact code in my WAMP server on windows....
It seemed to work perfectly smooth !!!
OUTPUT : 1.19 mBTC Is it what you expect????
I think your server is unable to access web pages, so, your php code variables are going vacant...try XAMP and check out ....
Thanks....
you can't crawler the data from https://coinbase.com/api/v1/prices/spot_rate
so $string is empty!
do {
$string = file_get_contents('https://coinbase.com/api/v1/prices/spot_rate');
} while (!empty($string));
$result = json_decode($string);
$spot = $result->amount;
$price = 2; //change this to your USD value
if (isset($spot) or $spot == 0) {
echo "\$spot is not islet or 0";
} else {
$whole = substr($price/$spot, 4, -13);
$dec = substr($price/$spot, 4, -12);
echo $whole.'.'.$dec.' mBTC';
}