Random number generator (device): Difference between revisions

m (A GlovePIE section has been added.)
Line 658:
2366495746
692037942</pre>
 
=={{header|Phix}}==
{{todo|Phix|Test once 0.8.0 is released.}}
My machine does not support the rdrand instruction.<br>
Tested as best I can by commenting out the jnc instructions and replacing rdrand with rdtsc.<br>
I have uploaded replacement pttree.e and pilasm.e (use at your own risk) for
anyone wanting to test prior to 0.8.0 being shipped.
 
If your chip does not support rdrand, you get {1,0}, else {0,-2147483648..2147483647}.<br>
For completeness, I have shown how to convert the signed result to an unsigned one.
 
<lang Phix>integer res -- 1=failure, 0=success
atom rint = 0 -- random 32-bit int
 
#ilASM{
mov eax,1
cpuid
bt ecx,30
mov edi,1 -- exit code: failure
jnc :exit
 
-- rdrand sets CF=0 if no random number
-- was available. Intel documentation
-- recommends 10 retries in a tight loop
mov ecx,11
::loop1
sub ecx, 1
jz :exit -- exit code is set already
rdrand eax
-- (the above generates exception #C000001D if not supported)
-- rdtsc
jnc :loop1
 
lea edi,[rint]
call :%pStoreMint
xor edi,edi
 
::exit
mov [res],edi
xor ebx,ebx -- important!
}
 
?{res,rint}
 
if res=0 then -- (success)
 
--
-- To convert a signed 32-bit int to an unsigned one:
--
-- method 1
-- atom urint1 = rint
-- if urint1<0 then urint1+=#100000000 end if
atom urint1 = rint+iff(rint<0?#100000000:0)
 
-- method 2
atom pMem = allocate(4)
poke4(pMem,rint)
atom urint2 = peek4u(pMem)
free(pMem)
 
-- method 3
atom urint3 = bytes_to_int(int_to_bytes(rint,4),signed:=false)
 
?{urint1,urint2,urint3}
 
end if</lang>
A linux-only solution:
<lang Phix>integer fn = open("/dev/urandom","rb")
if fn=-1 then
puts(1,"cannot open /dev/urandom\n")
else
sequence s = {}
for i=1 to 4 do
s &= getc(fn)
end for
close(fn)
?bytes_to_int(s,signed:=false)
end if</lang>
 
=={{header|PicoLisp}}==
7,804

edits