Возьмем пару алгоритмов псевдо рандом генераторов и один также псевдо, но генерируемый при помощи команды RDTSC.
1. Алгоритм который я уже рассматривал, это линейный конгруэнтный генератор, я не буду его подробно разбирать, это было сделано в статье про него, которую можно почитать тут.
Рисунок при
K0 = 1
A = 11
B = 23
G = 255
Получается такой:
По вертикальным чертам сразу видно, что генератор псевдо случайных писем повторяется, еслиб он не повторялся то рисунок был бы более хаотичный.
2. Алгоритм тоже достаточно извесный но я о нем еще не говорил и называется он BBS, от фамилий их создателей L. Blum, M. Blum, M. Shub
Этот алгоритм к стати интересен тем, что он не только генерит неплохие последовательности, но и также при известных значениях с которыми работал генератор можно вычислить любую Xn, не перебирая все варианты от X0 до Xn.
Формула сего алгоритма следующая:
Сначало выбираются 2 больших простых числа q и p.
Числа должны быть оба сравнимы с 3 по модулю 4, тоесть оба числа должны при взятии модуля 4 получать 3 в остатке. Например это числа: 31 и 51, если возвести их оба в модуль 4 получим 3.
Далее перемножаем p * q = M и выбираем взаимно простое число x, тоесть число которое не имеет с M одинаковых множетелей кроме 1. И вычисляем по формуле:
х0= (х*x) mod M
Ну а дальше как линейный конгруэнтный генератор, подставляем число x , получаем профит, тоесть вот эту картину:
3. И последний алгоритм добывания некоторого рандома, это команда RDTSC, которая считывает Time Stamp Counter. Эта команда полезна тем, что может быть в принципе источником энтропии. Алгоритм тут совсем простой, получаем число, смотрим на младший бит рисуем картинку:
Как видно даже вроде неплохой рандом получается, но реально использовать в серьезных программах народ в интернетах не рекомендует, хотя по мне, в полне нармально вроде получилось :)
Ну а теперь как обычно немного ассемблерного кода:
.386 .model flat, stdcall ;32 bit memory model option casemap :none ;case sensitive include checkRND.inc .code start: invoke createBMPHeader ; создаем заголовок BMP файла push eax ; сохраним ссылку на него invoke CreateFile, offset filename, GENERIC_WRITE,FILE_SHARE_WRITE, NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, 0 ; открываем фаил на запись mov hFile, eax ; сохраняем хендл invoke SetFilePointer, hFile, NULL,NULL, FILE_END ; ставим указатель на конец файла pop eax ; востановим ссылку на заголовок invoke WriteFile, hFile, offset hBMP, eax, ADDR cWrite, NULL ; записываем заголовок bmp mov ecx, IMGSIZE*IMGSIZE ; в ecx помещаем размер картинки nextpoint: push ecx ; сохраним ecx invoke SetFilePointer, hFile, NULL,NULL, FILE_END ;ставим указатель на конец файла invoke createColor ; создаем цвет FF - белый, 0 - черный invoke WriteFile, hFile, offset color, 1, ADDR cWrite, NULL ; записываем байт pop ecx ; востанавливаем ecx loop nextpoint ; обрабатываем следующий байт invoke CloseHandle, hFile ; закрываем хэндл invoke ExitProcess,0 ; выходим из программы createBMPHeader proc ; создаем заголовок bmp картинки mov hBMP.bfType, 'MB' ; записываем магическую комбинацию xor eax, eax ; обнуляем eax mov eax, sizeof ihBMP ; вычисляем размер, ахинея но пусть будет mov ihBMP.biSize, eax ; записываем размер всего файла, необязательный параметр mov ihBMP.biWidth, IMGSIZE ; пишем высоту mov ihBMP.biHeight, IMGSIZE ; пишем ширину mov ihBMP.biPlanes, 1h ; насколько я понял всегда еденица mov ihBMP.biBitCount, 1h ; бит на еденицу, значит монохромное mov bcol.rgbBlue, 0FFh ;цвет1 mov bcol.rgbGreen, 0FFh ;цвет1 mov bcol.rgbRed, 0FFh ;цвет1 xor eax, eax ; обнулили eax add eax, sizeof hBMP ; сложили файловый хидер bmp add eax, sizeof ihBMP ; сложили инфо хидер bmp add eax, sizeof wcol*2 ; прибавили цвета, 2 штуки mov hBMP.bfOffBits, eax ; записали в общий размер заголовка ret createBMPHeader endp createColor proc LOCAL tmpk:DWORD mov color, 0 ; изначально цвет 0 mov tmpk, 5h ; во временную перменную заносим 5 xor eax, eax ; обнуляем eax mov ecx, 8 ; так как в байте 8 бит, записываем в ecx 8 nextbit: mov eax, tmpk ; востанавливаем временную переменную ; invoke random ; разнообразные функции рандома ; invoke Gen_Ps_Random,eax, 0Bh, 17h, 0FFh ; разнообразные функции рандома invoke Gen_Bbs_Random,eax, 1Fh, 33 ; работающая BBS функция mov tmpk, eax ; сохраняем во временной переменной eax bt ax, 0 ; смотрим какой самый младший бит jc biton ; если 1, то прыгаем на biton mov al, color ; копируем число из color в al rol al, 1 ; сдвигаем al на 1 позицию mov color, al ; записываем в переменнюу color al jmp endbit прыгаем на конец обработки бита biton: ; если бит всетаки 1 mov al, color копируем число из color в al or al, 1 ; вклеиваем 1 в младший бит rol al, 1 ; сдвигаем al на 1 позицию mov color, al ; записываем в переменнюу color al endbit: loop nextbit ; обрабатываем следующий бит ret createColor endp random proc uses ebx edx ; самопальный рандом db 0fh,031h ;записываем команду RDTSC в хексе, чтобы не ругался компилятор neg eax ; инвентируем eax rcl eax, 5 ; сдвигаем в лево теряя один бит mov ebx, eax ; копируем eax в ebx mov edx, eax ; копируем eax в edx db 0fh,031h ;записываем команду RDTSC в хексе, чтобы не ругался компилятор rcr eax, 6 ; сдвигаем eax на 6 в право теряя один бит neg eax ; снова инвертируем eax xor eax, ebx ; ксорим eax и ebx Ret random EndP Gen_Ps_Random proc uses edx k:DWORD, a:DWORD, b:DWORD, g:DWORD mov eax, a ; копируем в eax a mul k ; умножаем eax на k add eax, b ; складываем eax с b xor edx, edx ; обнуляем edx div g ; берем модуль от g mov eax, edx ; копируем модуль в eax Ret Gen_Ps_Random EndP Gen_Bbs_Random proc uses edx ebx x:DWORD, p:DWORD, q:DWORD mov eax, x ; копируем в eax x mul eax ; умножаем eax на eax mov ebx, eax ; копируем eax в ebx mov eax, p ; копируем p в eax mul q ; умножаем на q xchg eax, ebx ; меняем местами eax и ebx xor edx,edx ; обнуляем edx div ebx ; вычисляем модуль mov eax, edx : копируем модуль в eax Ret Gen_Bbs_Random EndP end start
Ну и конечно целиком исходный код на pastebin - http://pastebin.com/kr3ArVfV
Комментариев нет:
Отправить комментарий