in python i do :
import random
while True:
x = random.randint(0xF,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140)
print hex(x)[2:66].lower()
how to do that using C or C++ ?
in python i do :
import random
while True:
x = random.randint(0xF,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140)
print hex(x)[2:66].lower()
how to do that using C or C++ ?
Using GNU MP library, this can be done like this:
#include <stdio.h>
#include <ctype.h>
#include <gmp.h>
void randint(mpz_t rop, gmp_randstate_t state, mpz_t from, mpz_t to) {
mpz_t range;
mpz_init(range);
/* range = to - from + 1 */
mpz_sub(range, to, from);
mpz_add_ui(range, range, 1);
/* rop = random number in [0, range) */
mpz_urandomm(rop, state, range);
/* rop += from */
mpz_add(rop, rop, from);
mpz_clear(range);
}
int main(void) {
char str[1024]; /* allocate enough memory */
gmp_randstate_t state;
mpz_t low, high;
mpz_t ret;
gmp_randinit_default(state);
mpz_init(ret);
mpz_init_set_str(low, "F", 16);
mpz_init_set_str(high, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140", 16);
for(;;) {
randint(ret, state, low, high);
str[0]='0'; str[1]='x';
mpz_get_str(str + 2, 16, ret);
if (str[0] != '\0' && str[1] != '\0') {
int i;
for (i = 2; i < 66 && str[i] != '\0'; i++) putchar(tolower(str[i]));
}
putchar('\n');
}
/* the control won't come here */
#if 0
mpz_clear(low);
mpz_clear(high);
mpz_clear(ret);
gmp_randclear(state);
return 0;
#endif
}
A very simple solution:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define StringLength (256/4) // (Bits you want)/4 (Thanks, chux)
int main(void){
char cStrHex[(StringLength+1)] = {0};
// Seed random:
srand((unsigned int) time(0));
// Fill the char buffer
int i=0;
for(; i < StringLength; i++){
sprintf(cStrHex+i, "%x", rand() % 16);
}
// Print hex string:
printf("%s\n", cStrHex);
return 0;
}
Please note that rand()
is not considered to be cryptographically secure, so replace calls to rand()
with a CSPRNG if you want to use this for anything requiring completely unpredictable random number. Nonetheless, this is a short, simple, and efficient solution to your problem.
Here's an approach that uses random()
. It attempts to use as many digits as possible. In case of POSIX random(), that's 31 bits, so 7 full digits. With, say, arc4random, you could use 8.
int max_usable_digits = 7;
uint64_t mask = (1 << (4 * max_usable_digits)) - 1;
const char *hex_digits = "0123456789abcdef";
std::string get_random_hex(int digits) {
char buffer[65] = {};
int offset = 0;
while (offset < sizeof(buffer)) {
long r = random() & mask;
offset += snprintf(buffer + offset, sizeof(buffer) - offset,
"%0*lx", max_usable_digits, r);
}
return std::string(buffer);
}
If you can use Boost library, generating_a_random_password example solves your problem with minor modifications.
UPDATE: This returns random strings between 64 zeros and 64 F's. The specific limits in OP's question (of 0xF and 0xFF..140) are a range of valid EDCSA keys. Nearly all 64-digit strings are valid. You can guarantee a number in the range with:
std::string min = "000000000000000000000000000000000000000000000000000000000000000F";
std::string max = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140";
std::string get_random_ecdsa_key() {
while (true) {
std::string s = get_random_hex(64);
if (s >= min && s < max) {
return s;
}
}
}