Blog. Just Blog

Генератор xoshiro64 на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
В качестве продолжения статьи про xoshiro128 реализация алгоритма xoshiro64 на Ассемблере. Напомню, что xoshiro (xoroshiro) - семейство высокоскоростных алгоритмов для генерации псевдослучайных чисел. Есть две разновидности xoshiro64, отличающиеся друг от друга только количеством операций умножения. Это, соответственно, версия xoshiro64* и xoshiro64**. Для работы генератор использует буфер размером в 2 DWORD'а.

В оригинальном алгоритме отсутствует функция инициализации, там достаточно просто записать какие-то начальные ненулевые значения в рабочий буфер. Если вам надо инициализировать и "прогреть" генератор, то я сделал для этого функцию по аналогии с xoshiro128. Но это уже моя самодеятельность, в авторском алгоритме ничего такого нет.
  1. ;---------------------------------------------
  2. ; Инициализация генератора случайных чисел
  3. ; stdcall long_jump,seed
  4. ;---------------------------------------------
  5. proc long_jump seed:DWORD
  6.         locals
  7.              s0 dd ?
  8.              s1 dd ?
  9.         endl
  10.  
  11.         pusha
  12.  
  13.         ; Начальное "засеивание" генератора
  14.         mov     edi,s
  15.         mov     eax,[seed]
  16.         rol     eax,1
  17.         xor     eax,0x1C580662
  18.         stosd
  19.         rol     eax,3
  20.         add     eax,0x0B6F099F
  21.         stosd
  22.  
  23.         ; Холостая прокрутка генератора для инициализации
  24.         lea     edi,[s0]
  25.         push    edi
  26.         xor     eax,eax
  27.         stosd
  28.         stosd
  29.  
  30.         xor     ebx,ebx
  31. .loc_for_1:
  32.         xor     ecx,ecx
  33. .loc_for_2:
  34.         mov     eax,[.lj+ebx*4]
  35.         and     eax,1
  36.         shl     eax,cl
  37.         jz      @f
  38.  
  39.         mov     esi,s
  40.         lodsd
  41.         xor     [s0],eax
  42.         lodsd
  43.         xor     [s1],eax
  44. @@:
  45.         stdcall next
  46.  
  47.         inc     ecx
  48.         cmp     ecx,32
  49.         jb      .loc_for_2
  50.  
  51.         inc     ebx
  52.         jnp     .loc_for_1
  53.  
  54.         pop     esi
  55.         mov     edi,s
  56.         movsd
  57.         movsd
  58.  
  59.         popa
  60.         ret
  61.  
  62. .lj:    dd 0xB523952E
  63.         dd 0x0B6F099F
  64. endp
Инициализация выполняет первичное "засеивание" рабочего буфера, а затем делает 264 холостых прогонов генератора с одновременным перемешиванием данных рабочего буфера.

Функции генерации соответствуют предъявляемым требованиям по уникальности и распределению результатов, а за счет использования операций умножения не допускают появления линейных артефактов в младших битах.
  1. ;---------------------------------------------
  2. ; Получить случайное число xoshiro64*
  3. ; stdcall next
  4. ; на выходе EAX - случайное число
  5. ;---------------------------------------------
  6. proc next
  7.         pusha
  8.  
  9.         xor     edx,edx
  10.         mov     eax,[s+0*4]
  11.         mov     ecx,0x9E3779BB
  12.         mul     ecx
  13.         mov     [esp+28],eax
  14.  
  15.         mov     eax,[s+0*4] ; s[0]
  16.         mov     ebx,[s+1*4] ; s[1]
  17.         xor     ebx,eax
  18.         mov     edx,ebx
  19.  
  20.         mov     ebx,eax
  21.         shr     ebx,(32-26)
  22.         shl     eax,26
  23.         or      eax,ebx
  24.  
  25.         mov     ebx,edx
  26.         xor     eax,ebx
  27.         shl     edx,9
  28.         xor     eax,edx
  29.         mov     [s+0*4],eax
  30.  
  31.         mov     eax,ebx
  32.         shr     ebx,(32-13)
  33.         shl     eax,13
  34.         or      eax,ebx
  35.  
  36.         mov     [s+1*4],eax
  37.  
  38.         popa
  39.         ret
  40. endp
  1. ;---------------------------------------------
  2. ; Получить случайное число xoshiro64**
  3. ; stdcall next
  4. ; на выходе EAX - случайное число
  5. ;---------------------------------------------
  6. proc next
  7.         pusha
  8.  
  9.         xor     edx,edx
  10.         mov     eax,[s+0*4]
  11.         mov     ecx,0x9E3779BB
  12.         mul     ecx
  13.  
  14.         mov     ebx,eax
  15.         shr     ebx,(32-5)
  16.         shl     eax,5
  17.         or      eax,ebx
  18.  
  19.         xor     edx,edx
  20.         mov     ecx,5
  21.         mul     ecx
  22.         mov     [esp+28],eax
  23.  
  24.         mov     eax,[s+0*4] ; s[0]
  25.         mov     ebx,[s+1*4] ; s[1]
  26.         xor     ebx,eax
  27.         mov     edx,ebx
  28.  
  29.         mov     ebx,eax
  30.         shr     ebx,(32-26)
  31.         shl     eax,26
  32.         or      eax,ebx
  33.  
  34.         mov     ebx,edx
  35.         xor     eax,ebx
  36.         shl     edx,9
  37.         xor     eax,edx
  38.         mov     [s+0*4],eax
  39.  
  40.         mov     eax,ebx
  41.         shr     ebx,(32-13)
  42.         shl     eax,13
  43.         or      eax,ebx
  44.  
  45.         mov     [s+1*4],eax
  46.  
  47.         popa
  48.         ret
  49. endp
В приложении примеры программ с исходными текстами, которые используют алгоритмы xoshiro64* и xoshiro64** для генерации псевдослучайных чисел.

Примеры программ с исходными текстами (FASM)Примеры программ с исходными текстами (FASM)

xoshiro64.Demo.zip (6,297 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 785 | Комментариев: 4

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (24.05.2023 в 16:23):
Grey, цель рандома не просто нагенерить мусора, а чтобы на его основе нельзя было вычислить последовательность и, соответственно, предсказать следующий результат. Xn+1=A*Xn*(1-Xn), как мне кажется, такой уверенности не дает, чисто для бытовых нужд, запускать снежинки по экрану.
Grey (24.05.2023 в 16:19):
Смотрел ролик про бифуркацию. Там в частности говорилось, что одно из применений - генератор псевдослучайных чисел. Xn+1=A*Xn*(1-Xn). Значение А принимается от 3,5 до 4. В экселе посмотрел, вроде похоже. Насколько это пригодно в жизни - трудно сказать.
ManHunter (19.08.2021 в 14:21):
"Прогреть" генератор - не просто инициализировать его начальным значением, но и сразу же вхолостую сгенерировать стопицот чисел, чтобы избежать возможных коллизий на старте и максимально исказить рабочий буфер перед боевым применением генератора.

А где может пригодиться? Да где угодно, если там нужны случайные числа. Или реферат по программированию накатать.
art2021 (19.08.2021 в 14:16):
ЦитатаЕсли вам надо инициализировать и "прогреть" генератор

Что значит "прогреть" генератор - если можно, то чуть поподробней.

И еще хотел спросить, а где и в каких случаях этот алгоритм может пригодится? Спасибо.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.08 сек. / MySQL: 2 (0.0065 сек.) / Память: 4.5 Mb
Наверх