LCF-AT Posted April 29, 2021 Posted April 29, 2021 Hi again, short question.I wanna create random values (0 till -1h) and found 2 C++ function called rand and srand. https://www.cplusplus.com/reference/cstdlib/rand/ https://www.cplusplus.com/reference/cstdlib/srand/ So if I check it right then I have to call first srand with any value X as paramter and then calling rand right after.If I do that to call srand first with same value like 10h then I get a results of 5Ah back from rand function.So is it just to prevent creating same random values?Should I call it like this below each time if I need to create a random value? .data holder dd FALSE invoke crt_srand, holder invoke crt_rand inc holder or invoke crt_srand, holder invoke crt_rand mov holder, eax Something like this?Of course I dont wanna get the same random values back.Just wanna be sure to get always diffrent values anyway how much I call the functions in a running process you know.So what do you say? greetz
kao Posted April 29, 2021 Posted April 29, 2021 It's all explained in the document you linked to: https://www.cplusplus.com/reference/cstdlib/rand/ This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using function srand. and later in the example: /* initialize random seed: */ srand (time(NULL)); /* generate secret number between 1 and 10: */ iSecret = rand() % 10 + 1; That's the most common approach - initializing random number generator with the current time or output of rdtsc instruction. Using counter like you suggested is not a good idea. Instead, you could call srand() just once at the beginning of your program - it's perfectly fine for simple things (but don't use it to generate password for your bank..) 3
LCF-AT Posted April 29, 2021 Author Posted April 29, 2021 Hi, still not sure how you do mean it how I should do it. So you mean I should just call srand only once with NULL and later if I need for example diffrent random values I should just call rand alone each time?How can i be sure that I always get diffrent random values out after calling rand for x thousend times? greetz
kao Posted April 29, 2021 Posted April 29, 2021 30 minutes ago, LCF-AT said: I should just call srand only once with NULL Don't call srand with zero, that will give you always the same sequence of numbers. As I already wrote: 26 minutes ago, kao said: That's the most common approach - initializing random number generator with the current time or output of rdtsc instruction. 15 minutes ago, LCF-AT said: How can i be sure that I always get diffrent random values out after calling rand for x thousend times? If you don't want to study the math behind it, just accept that as a fact. In case of generator in msvcrt.dll, it returns values between 0 and 32767, so you should get 32k different numbers out of it. 2
Progman Posted April 30, 2021 Posted April 30, 2021 Using modulo on the RNG result introduces statistical bias. Trimming bits is okay though. Such RNG are not cryptographically secure either and lead to security flaws. Seeding was traditionally done with the time(null) call as number of seconds since Jan1 1970 is practically speaking always changing at a fast enough rate. Other sources of entropy are possible but less trivial to gather e.g. heat values from motherboard or mouse movement 1
fearless Posted April 30, 2021 Posted April 30, 2021 include bcrypt.inc includelib bcrypt.lib GenRandom PROTO GenRandom PROC LOCAL dwRandom:DWORD mov dwRandom, 0 Invoke BCryptGenRandom, NULL, Addr dwRandom, 4, BCRYPT_USE_SYSTEM_PREFERRED_RNG ;0x00000002 mov eax, dwRandom ret GenRandom ENDP 3
ToMKoL Posted April 30, 2021 Posted April 30, 2021 Here is old example from WiteG site: rand proc nBits:DWORD push ebx push esi push ecx push edx mov ebx, nBits ;how many bits in result: 1 to 32 xor esi, esi _rand_loop: call GetTickCount ; pseudo-random add eax, seed imul eax, 343FDh ; standardowa C function add eax, 269EC3h ; rand() mov seed, eax ; shr eax, 10h ; and eax, 7FFFh ; mov ecx, eax ; guess xor edx, edx ; imul eax, ecx ; imul eax, ecx ; div dword ptr [const] ; and edx, 1 ; get zero bit shl esi, 1 or esi, edx ; and save as next bit in result dec ebx jnz _rand_loop mov eax, esi pop edx pop ecx pop esi pop ebx ret const dd 0D76D7249h seed dd 0 rand endp Usage: push 1 ;to 32 call rand 1
Progman Posted April 30, 2021 Posted April 30, 2021 (edited) That is a linear congruential generator LCG with period of 2^16 per birthday theorem. The multiplication addition though is fast and simple. Generally modern contexts should have 2^64 period minimum. Better is the famous Mersenne Twister algorithm. I've not seen it in hand written assembler but it would be too difficult. 2^19337-1 proven periodicity though is impressive. Not for security still. Windows API is easiest if a secure one is needed. If you need a value between 0 and x. Determine log2 by finding the bit size. If number from RNG truncated to bit size is still bigger than x, get another random number otherwise use it. Now you dont cause statistical bias due to modulo. On average 1-2 calls to get a random number depending on how far x is from Rounding up to nearest power of 2. Edited May 1, 2021 by Progman 1
Teddy Rogers Posted May 1, 2021 Posted May 1, 2021 12 hours ago, fearless said: include bcrypt.inc includelib bcrypt.lib GenRandom PROTO GenRandom PROC LOCAL dwRandom:DWORD mov dwRandom, 0 Invoke BCryptGenRandom, NULL, Addr dwRandom, 4, BCRYPT_USE_SYSTEM_PREFERRED_RNG ;0x00000002 mov eax, dwRandom ret GenRandom ENDP +1 for BCryptGenRandom or the older CryptGenRandom (RtlGenRandom) API - though these older API's are now deprecated... Ted. 1
CodeExplorer Posted May 14, 2021 Posted May 14, 2021 (edited) https://stackoverflow.com/questions/11946622/implementation-of-random-number-generator https://stackoverflow.com/questions/37396278/how-to-generate-very-large-random-number-in-c/37396515 static unsigned int seed = 1; void usrand (unsigned int newseed) { seed = newseed; // & 0x7fffffffU } unsigned int urand(void) { seed = (seed * 1103515245U + 12345U); // & 0x7fffffffU return (unsigned int)seed; } // init random generator: usrand(time(NULL)); srand(time(NULL)); But you are right, if seed is guessed all random values can be calculated. One way may be to make seed harder to guess seed = seed^value but don't know yet what to put as value. Edited May 14, 2021 by CodeExplorer 1
Xyl2k Posted May 16, 2021 Posted May 16, 2021 GenRandomNumbers Proc uses ebx pIn:DWORD,pLen:DWORD mov edi,pIn mov ebx,pLen .repeat invoke Randomize mov ecx,32 ; Change this number to a new Alphabet size if your gonna modify it xor edx,edx idiv ecx movzx eax,byte ptr [edx+B32Chars] stosb dec ebx .until zero? Ret GenRandomNumbers endp Randomize Proc uses ecx invoke GetTickCount add Rndm,eax add Rndm,eax add Rndm,'abcd' Rol Rndm,4 mov eax,Rndm ; imul eax,'seed' Ret Randomize endp not really random but do the job numbers-letters.zip 1
sama Posted May 16, 2021 Posted May 16, 2021 .data Seed dd 012345678h RandomRange proc uses esi edi ebx _RangeLow:dword, _RangeHigh:dword mov esi,_RangeHigh mov ebx,_RangeLow .if esi < ebx mov eax,ebx sub eax,esi call RandomInt add eax,esi .else mov eax,esi sub eax,ebx call RandomInt add eax,ebx .endif ret RandomRange endp RandomInt Proc uses ebx push ebx xor ebx,ebx imul edx,dword ptr[ebx+Seed],08088405h inc edx mov dword ptr[ebx+Seed],edx mul edx mov eax,edx pop ebx ret RandomInt endp Randomize Proc add esp,-8 push esp call QueryPerformanceCounter test eax,eax je @F mov eax,dword ptr[esp] mov dword ptr[Seed],eax pop ecx pop edx ret @@: call GetTickCount mov dword ptr[Seed],eax pop ecx pop edx Ret Randomize endp maybe an alternative, have a nice day 1
LCF-AT Posted May 16, 2021 Author Posted May 16, 2021 Hi guys, thanks for posting another example codes to generate some random numbers. At the moment I'am just generate & using random numbers for my listviews and every single entry to store them into a sturct in lparam.Some kind of unique ID to recognize the entry from any location which is needed if you work with X threads so then I just need to send the random ID / Handle / optional other info / with the threads.I thinks its a better method to do that instead sending visible entry infos like position or entry name etc which can be quickly changed by user itself durring the process.The random value is hidden and unique and in this case I just need to check the entire LV to find it each time if I wanna change / update some infos for that entry if the random value is still present. Not sure whether its smart to G-alloc a struct of X bytes for every single LV & entry (+1000) but should be and is working fine so far. greetz
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now