Как получить случайные байты на этапе компиляции?
Как можно получить N байт на этапе компиляции максимально просто?
constexpr unsigned char bytes[] = ???;
Как можно получить N байт на этапе компиляции максимально просто?
constexpr unsigned char bytes[] = ???;
dd if=/dev/urandom of=./randomkey.bin bs=32 count=1
xxd -n bytes -i ./randomkey.bin ./randomkey.h
rm ./randomkey.bin
Сгенерирует заголовочный файл, который можно ставить через #include в нужное место.
unsigned char bytes[] = {
0x72, 0xdb, 0x7c, 0x53, 0x3a, 0x13, 0xad, 0x76, 0xfa, 0x94, 0xf2, 0xd2,
0x6a, 0x8c, 0xcd, 0x87, 0xdd, 0x4e, 0x3f, 0x8a, 0xf3, 0x61, 0xc2, 0x9f,
0xcd, 0xc6, 0x6a, 0x25, 0xc6, 0x7e, 0x8c, 0x7e
};
unsigned int bytes_len = 32;
#include <boost/preprocessor/repeat.hpp>
#define RAND_CHARS_ITEM(_unused1, I, SEED) (unsigned char)( ( size_t( (I^2531011u) *1222943u + SEED )%214013u ^(23167u) ) ),
#define RAND_CHARS( SIZE, SEED ) BOOST_PP_REPEAT(SIZE, RAND_CHARS_ITEM, SEED)
#define RAND_SEED() ( (__TIME__[3] + __TIME__[6]*11u + __TIME__[5]*19u ) *32803u + __LINE__*17u +12224189u )
unsigned char bytes[] = { RAND_CHARS(128, RAND_SEED() ) };
Получим:
bytes:
.ascii "t\245\326\004\263\344\025F\365#T\2054b\223\304s\244\322\003\262"
.ascii "\343\021B\361\"S\2010a\222\300o\240\321\002\261\337\020A\360"
.ascii "\036O\200/`\216\277n\237\315\376\255\336\017=\354\035N|+\\\215"
.ascii "\276~\257\335\016\275\356\037M\374-^\214;l\235\316}\253\334\r"
.ascii "\274\352\033L\373,Z\213:k\231\312y\252\333\t\270\351\032H\367"
.ascii "(Y\2129g\230\311x\246\327\b\267\350\026G\366'U\2065f\227\305"
Метод тот же что и у @eri, но хочется немного развернуть ответ. Идея в том чтобы вставлять случайные байты на этапе компляции через директивы препроцессора. Большинство компиляторов позволяют определять константы препроцессора через флаг -D
.
#include <iostream>
#include <iomanip>
#ifndef RANDOM_BYTES
#define DUMMY_BYTES 0x00
#define RANDOM_BYTES DUMMY_BYTES
#endif
int
main()
{
constexpr unsigned char bytes[] = {
RANDOM_BYTES
};
for (unsigned int i : bytes) {
std::cout
<< std::hex
<< std::setw(2)
<< std::setfill('0')
<< i
<< ' ';
}
std::cout << std::endl;
}
По необходимости, определяем RANDOM_BYTES
чтобы избежать предупреждений компилятора и линтера. Это полезно если в вашем редакторе кода используется автоматическая проверка файла через LSP или его аналоги. Однако в случае если RANDOM_BYTES
не была определена во время компиляции, то компилятор молча подставит DUMMY_BYTES
!
И соответствующий Makefile:
LEN := 128
BYTES := $(shell dd if=/dev/urandom bs=$(LEN) count=1 status=none | xxd -i)
main: main.cpp
@g++ -D"RANDOM_BYTES=$(BYTES)" -o $@ $<
.DELETE_ON_ERROR:
Есть также статья «Random number generator for C++ template metaprograms», в которой предлагается, compile-time решение с помощью шаблонов.