Случайные чиселки на апи

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by desTiny, 24 Oct 2010.

  1. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Возник вопрос --- как генерировать случайные числа по типу функции rand() в crt, не очень заморачиваясь с реализацией, но crt всё-таки не используя. RtlRandom(Ex) ведут себя как-то очень странно -- почему-то последовательности, выдаваемые со снапшота на виртуалке совпадают, хотя seed разный.

    Спасибо.
     
  2. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Что мешает написать функции рандома самому, основываясь на сдвиговом регистре?
    Вот пример реализации на асме, она не зависит вообще ни от чего, кроме GetSystemTime для получения seed'а.

    PHP:

    Randomize PROC
    .data
    sysTime SYSTEMTIME 
    <>    ; system time structure
    .code
          pushad

          INVOKE GetSystemTime
    ,OFFSET sysTime
          movzx eax
    ,sysTime.wMilliseconds
          mov   seed
    ,eax

          popad
          ret
    Randomize ENDP


    Random32  PROC
    .data
    seed  DWORD 1
    .code
          push  edx
          mov   eax
    343FDh
          imul  seed
          add   eax
    269EC3h
          mov   seed
    eax
          ror   eax
    ,8
          pop   edx

          ret
    Random32  ENDP
    И кстати в Visual Studio проект можно собрать без зависимостей к CRT, она будет включена внутрь программы.
     
    1 person likes this.
  3. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    а вообще можно не мучаться, а взять исходники CRT и глянуть.
    Code:
    unsigned int RandomVar;
    
    void __cdecl my_srand(unsigned int seed)
    {
    	RandomVar = seed;
    	return;
    }
    
    
    int __cdecl my_rand(void)
    {
    	return( ((RandomVar = RandomVar * 214013L + 2531011L) >> 16) & 0x7fff );
    }
    
    
    Лично я для своих целей для my_srand делаю инициализацию не по времени а по отсчетам тактов процессора (более короткий код)
    Code:
    __declspec(naked) ULONG __inline my_rdtsc()
    {
    	__asm
    	{
    		rdtsc
    		xor eax, edx
    		ret
    	}
    }
    
     
    1 person likes this.
  4. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Спасибо, в crt действительно стоило заглянуть, но от него я ожидал большего )
    В дельфях так же примерно делалось; но интересны именно константы. Надеюсь, хоть они не с потолка взяты.

    //slesh, есть встроенное __rdtsc ;)