Информация об изменениях

Сообщение Re: Случайный пароль от 20.05.2023 14:59

Изменено 20.05.2023 19:35 L_G

Re: Случайный пароль
По поводу истинно случайного seed: если колхозить самому, то 2 хороших источника истинной случайности — это кадры с видеокамеры и аудиоданные со звукового входа (хоть микрофонного, хоть линейного), т.е. АЦП. Любой АЦП шумит, нужно этот шум и брать, т.е. только N младших бит от каждого сабпикселя/сэмпла (и лучше N=1, хотя может быть надежнее проксорить между собой N младших битов, N=3..4).
(Известно, что XOR двух случайных чисел неизвестного качества даст случайное число качеством НЕ ХУЖЕ лучшего из исходных.)

С доступом к этим устройствам, понятно, гемор, но, кажется, есть еще вариант: если в цикле замерять время исполнения одного маленького кусочка кода, то время будет каждый раз немножко разное, и немного истинной случайности в этом не может не быть. Опять же надежнее проксорить несколько младших битов (получая 1 случайный бит за 1 цикл/замер).
Замерять лучше функцией, использующей процессорную инструкцию rdtsc (надеюсь, есть в используемых стандартных библиотеках) или WinAPI-шной QueryPerformanceCounter.
Пример на коленке (100 голых вызовов этой самой rdtsc, результаты замеров, в т.ч. побитно и 1 нужный нам случайный бит. Если что, сорри, я далек от С++):
#include <iostream>
#include <bitset>
#include <intrin.h> // есть не везде. на godbolt есть в MinGW (clang/gcc12). где-то - <x86intrin.h>
#pragma intrinsic(__rdtsc)

int main() {
    unsigned __int64 c = 0, c0;
    int ii[100];
    for (int i = 0; i < 100; ++i) {
      c0 = c; c = __rdtsc();
      ii[i] = c - c0;
    }
    for (int i = 0; i < 100; ++i) {
      std::cout << ii[i] << ' ' << std::bitset<16>(ii[i]) << ' ' << ((ii[i] ^ ii[i] >> 1 ^ ii[i] >> 2 ^ ii[i] >> 3) & 1) << std::endl;
    }
}

https://godbolt.org/z/vdEor15bq
(Распределение не особо равномерное, но закономерности явно нет. Последний бит почему-то всегда 0. поэтому и ксорю 4 последних.)
UPD: выкинул output из цикла замеров
Re: Случайный пароль
По поводу истинно случайного seed: если колхозить самому, то 2 хороших источника истинной случайности — это кадры с видеокамеры (объектив, закрытый "шторкой" — не помеха) и аудиоданные со звукового входа (хоть микрофонного, хоть линейного, отсутствие подключенного источника — не помеха), т.е. АЦП. Любой АЦП шумит, нужно этот шум и брать, т.е. только N младших бит от каждого сабпикселя/сэмпла (и лучше N=1, хотя может быть надежнее проксорить между собой N младших битов, N=3..4).
(Известно, что XOR двух случайных чисел неизвестного качества даст случайное число качеством НЕ ХУЖЕ лучшего из исходных.)

С доступом к этим устройствам, понятно, гемор, но, кажется, есть еще вариант: если в цикле замерять время исполнения одного маленького кусочка кода, то время будет каждый раз немножко разное, и немного истинной случайности в этом не может не быть. Опять же надежнее проксорить несколько младших битов (получая 1 случайный бит за 1 цикл/замер).
Замерять лучше функцией, использующей процессорную инструкцию rdtsc (надеюсь, есть в используемых стандартных библиотеках), как вариант — WinAPI-шной QueryPerformanceCounter.
Пример на коленке (100 голых вызовов этой самой rdtsc, результаты замеров, в т.ч. побитно и 1 итоговый "true-случайный" бит на замер. Если что, сорри, я далек от С++):
#include <iostream>
#include <bitset>
#include <intrin.h> // есть не везде. на godbolt есть в MinGW (clang/gcc12). где-то - <x86intrin.h> (например, в ICC)
#pragma intrinsic(__rdtsc)

int main() {
    unsigned __int64 c = 0, c0;
    int a[100];
    for (int i = 0; i < 100; ++i) {
      c0 = c; c = __rdtsc();
      a[i] = c - c0;
    }
    for (int i = 0; i < 100; ++i) {
      std::cout << a[i] << ' ' << std::bitset<8>(a[i]) << ' ' << ((a[i] ^ a[i] >> 1 ^ a[i] >> 2 ^ a[i] >> 3) & 1) << std::endl;
    }
}

https://godbolt.org/z/vdEor15bq
(Распределение не особо равномерное, но закономерности явно нет. Младший бит почему-то всегда 0 — поэтому и ксорю 4 младших.)
UPD: выкинул output из цикла замеров