Skip to content

Instantly share code, notes, and snippets.

@SammyK
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SammyK/4b4fc63babf3c31b4a64 to your computer and use it in GitHub Desktop.
Save SammyK/4b4fc63babf3c31b4a64 to your computer and use it in GitHub Desktop.
Ripped this out of the PHP CRPRNG PR since it got no love! :'(
// Copy/pasted from string.c
static char hexconvtab[] = "0123456789abcdef";
// Copy/pasted from string.c
static zend_string *php_bin2hex(const unsigned char *old, const size_t oldlen)
{
zend_string *result;
size_t i, j;
result = zend_string_safe_alloc(oldlen, 2 * sizeof(char), 0, 0);
for (i = j = 0; i < oldlen; i++) {
result->val[j++] = hexconvtab[old[i] >> 4];
result->val[j++] = hexconvtab[old[i] & 15];
}
result->val[j] = '\0';
return result;
}
/* {{{ proto string random_hex(int str_len)
Return an arbitrary length of pseudo-random bytes as hexadecimal string */
PHP_FUNCTION(random_hex)
{
zend_long size;
zend_long bytes_size;
zend_string *bytes;
zend_string *hex;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &size) == FAILURE) {
return;
}
if (size <= 0 || size > INT_MAX) {
php_error_docref(NULL, E_WARNING, "Cannot genrate a random string with a size of less than 1 or greater than %d", INT_MAX);
RETURN_FALSE;
}
bytes_size = ceil(size / 2);
bytes = zend_string_alloc(bytes_size, 0);
if (php_random_bytes(bytes->val, bytes_size) == FAILURE) {
zend_string_release(bytes);
return;
}
hex = php_bin2hex((unsigned char *)bytes->val, bytes->len);
zend_string_release(bytes);
if (!hex) {
RETURN_FALSE;
}
// @todo This feels wrong but it works
if (size % 2 != 0) {
zend_string *hex_odd = zend_string_alloc(size, 0);
memcpy(hex_odd->val, hex->val, size);
zend_string_release(hex);
RETURN_STR(hex_odd);
}
RETURN_STR(hex);
}
/* }}} */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment