473,382 Members | 1,648 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Cryptographically random numbers

Okay, I'm working on devoloping a simple, cryptographically secure
number, from a range of numbers (As one might do for finding large
numbers, to test if they are prime). My function looks like this:

def cran_rand(min,max):
if(min>max):
x=max
max=min
min=x
range=round(log(max-min)/log(256))
if range==0:
range=1
num=max+1
while(num>max):
num=min+s2num(urandom(range))
return num

Any comments on this? I think it should hold up to a test, it seems to
work alright. Thanks!

Mar 4 '06 #1
24 1897
> def cran_rand(min,max):

You're shadowing built-ins here. Not a problem, but something I'd generally
avoid.

if(min>max):
x=max
max=min
min=x
If the args were a,b you could say:

maxarg,minarg = min(a,b),max(a,b)

range=round(log(max-min)/log(256))
more builtin shadowing...
if range==0:
range=1
or as alt_name_for_range=... or 1
num=max+1
while(num>max):
num=min+s2num(urandom(range))
I'll assume os.urandom is urandom. What's s2num?
return num

Any comments on this? I think it should hold up to a test, it seems to
work alright. Thanks!

If this does what you want, that's good. But someday when you look again
and see

while(num>max): num=min+s2num(urandom(range))

you'll wonder...

Thankfully-python-uses-int-and-not-num-ly y'rs,

Emile van Sebille
em***@fenx.com



Mar 5 '06 #2
Good idea about the max and min values. Yes, urandom is os.urandom.
s2num('blah') will convert the phrase blah to ascii, and treat them as
if they were a big function.

Anyone else whose still interested, I found another small bug, but it
was in the modular (Again). It won't do much, but...

I did test out the RSA from end to end, found another small bug (I
imputed the text luke, and it decrypted to ekul), but it works good
now. Hopefully there's nothing left gaping, thanks for the help!

Mar 5 '06 #3
Tuvas wrote:
Okay, I'm working on devoloping a simple, cryptographically secure
number, from a range of numbers (As one might do for finding large
numbers, to test if they are prime). My function looks like this:

def cran_rand(min,max):
if(min>max):
x=max
max=min
min=x
range=round(log(max-min)/log(256))
if range==0:
range=1
num=max+1
while(num>max):
num=min+s2num(urandom(range))
return num

Any comments on this? I think it should hold up to a test, it seems to
work alright.


Have to disagree. Try:

for _ in range(100):
print cran_rand(0, 500)

How many numbers greater than 255 do you get?
I have more comments, but that's the biggest issue.
--
--Bryan
Mar 6 '06 #4
Ahh, you are correct, that is a large bug... How about this one?

def s2num(text):
if(len(text)==1):
return ord(text)
else:
return ord(text[0])+256*s2num(text[1:])

def cran_rand(min,max):
range=int(log(abs(max-min))/log(2))+1
num=max+1
if range%8==0:
crange=range/8
else:
crange=range/8+1
while(num>max):
num=min+s2num(urandom(crange))%(2**range)
return num

Mar 7 '06 #5
"Tuvas" <tu*****@gmail.com> writes:
def s2num(text):
if(len(text)==1):
return ord(text)
else:
return ord(text[0])+256*s2num(text[1:])
My favorite way to convert strings to numbers is with binascii:
from binascii import hexlify
def s2num(text):
return int(hexlify(text), 16)
def cran_rand(min,max):
range=int(log(abs(max-min))/log(2))+1


This is kind of ugly and I wonder if it's possible for roundoff error
in the log function to make the answer off by 1, if max-min is very
close to a power of 2.
Mar 7 '06 #6
Paul Rubin wrote:
My favorite way to convert strings to numbers is with binascii:

from binascii import hexlify
def s2num(text):
return int(hexlify(text), 16)

Neat. I use the empty string as a binary representation of zero,
which you can accommodate with:

def s2num(text):
return int(hexlify(text) or '0', 16)
--
--Bryan
Mar 7 '06 #7
Wait, I now see that there is a native base 2 log in python, so I will
just do that rather than my adhoc way. The reason for adding one is to
make sure there isn't any problems if the log is, for instance, 2.2. It
will always round up. It's better to have to try twice to make sure the
number can have the max range than never use the top half, as the first
version did... That changes the function to:

def cran_rand(min,max):
range=int(log(abs(max-min),2))+1
num=max+1
if range%8==0:
crange=range/8
else:
crange=range/8+1
while(num>max):
num=min+s2num(urandom(crange))%(2**range)
return num

As to the s2num(text), well, that looks really neat. Is there an easy
way to do the reverse of that? Thanks!

Mar 7 '06 #8
"Tuvas" <tu*****@gmail.com> writes:
Wait, I now see that there is a native base 2 log in python, so I will
just do that rather than my adhoc way. The reason for adding one is to
make sure there isn't any problems if the log is, for instance, 2.2. It
will always round up. It's better to have to try twice to make sure the
number can have the max range than never use the top half, as the first
version did... That changes the function to:
OK, if the log is one too high, you just have to do a few additional
retries.
As to the s2num(text), well, that looks really neat. Is there an easy
way to do the reverse of that? Thanks!


from binascii import unhexlify
def num2s(n):
s = '%X' % n
if len(s) % 2 == 1:
s = '0' + s # make sure length of hex string is even
return unhexlify(s)
Mar 7 '06 #9
Tuvas wrote:
Ahh, you are correct, that is a large bug... How about this one?


Much better. Do note the comments from Emile van Sebille and Paul
Rubin. There are some minor style and efficiency points, but it
looks reasonable.

Incidentally, as of Python 2.4, the standard library offers
random.SystemRandom, which will generate integers in any desired
range using os.urandom as the entropy source.
--
--Bryan
Mar 7 '06 #10
Wow, that would have been nice to know... Oh well, I've already got the
function, might as well use it... I'm starting to learn alot more of
the standard libraries that exist for alot of the little functions. It
seems like every project I have I build a misc.py file that contains
several small, but useful functions, and quite often I discover there
is a system library function to do just that. Oh well. Still, I've gone
a long ways in my Python skills since I started 6 months ago:-)

Mar 7 '06 #11
Tuvas wrote:
[...]
As to the s2num(text), well, that looks really neat. Is there an easy
way to do the reverse of that? Thanks!


Easy? Well, you be the judge:

def num2string(n):
""" Pass a non-negative int or long n.
Returns a string with bytes holding the big-endian base-256
representation of n. Zero is represented by the empty string.
"""
h = hex(n).lstrip('0x').rstrip('Ll')
if len(h) % 2:
h = '0' + h
return unhexlify(h)

I did a little testing:

for i in xrange(300):
assert s2num(num2string(i)) == i
for i in xrange(1, 20):
for _ in xrange(100):
r = os.urandom(i)
assert num2string(s2num(r)) == r.lstrip(chr(0))

--
--Bryan
Mar 7 '06 #12
Thanks for the function Paul, it works alot nicer than the one I had in
my program... Now, with all of this knowledge, I'm going to be brave
and try out everything with AES. It seems to be working alright, I'll
debug this more on my own than I did with my RSA code, which turned out
to be full of bugs... I know the program sends the blocks in the
reverse order that would be expected, but, well, I'll get there.
Cryptology is fun:-)

Mar 7 '06 #13
Bryan Olson wrote:
Tuvas wrote:
Ahh, you are correct, that is a large bug... How about this one?

Much better. Do note the comments from Emile van Sebille and Paul
Rubin. There are some minor style and efficiency points, but it
looks reasonable.

Incidentally, as of Python 2.4, the standard library offers
random.SystemRandom, which will generate integers in any desired
range using os.urandom as the entropy source.


How can I generate a random string containing digits, symbols and
letters? I will use this random string for the key of a cryptographic
algorithm.
Thanks

Mar 7 '06 #14
from os import urandom
def cstring(bytes):
ret=''
while(len(ret)<bytes):
c=os.urandom(1)
if c>'0' and c<'z':
ret=ret+c
return ret

That should do it, though I bet there might be a more efficient way. I
don't know if that's the set of characters you want to use, but... If
you want a better answer, you'd have to be more specific.

Mar 7 '06 #15
Gervasio Bernal <ge************@speedy.com.ar> writes:
How can I generate a random string containing digits, symbols and
letters? I will use this random string for the key of a cryptographic
algorithm.


Generally if this is a string that some human user has to type in,
it's preferable to select some words randomly from a dictionary rather
than use an easily-garbled string of symbols. If the string will be
handled entirely by computers, just use a random string of bytes (like
os.urandom(20)) without worrying about whether they're printable
characters. If you really want a random-looking string of specific
characters, a simple way is:

usable_characters = string.letters + string.digits
...
# generate one character from the set (repeat as needed)
a,b = map(ord, os.urandom(2))
c = (a*256 + b) % len(usable_characters)

Notice that the characters will have slightly unequal probability
(unless the usable character set's size is a power of 2), but the
effect on the output entry is insignificant.
Mar 7 '06 #16
Tuvas wrote:
from os import urandom
def cstring(bytes):
ret=''
while(len(ret)<bytes):
c=os.urandom(1)
if c>'0' and c<'z':
ret=ret+c
return ret

That should do it, though I bet there might be a more efficient way. I
don't know if that's the set of characters you want to use, but... If
you want a better answer, you'd have to be more specific.

Thanks a lot, that is what I need.
If someone else have a more efficient way I will appreciate.
Mar 7 '06 #17
I will admit though, I have the same question as Paul, why do you want
a random string of numbers, letters, and symbols? But, you asked for
it, so, that'll do.

Mar 7 '06 #18
"Tuvas" <tu*****@gmail.com> writes:
from os import urandom
def cstring(bytes):
ret=''
while(len(ret)<bytes):
c=os.urandom(1)
if c>'0' and c<'z':
ret=ret+c
return ret

That should do it, though I bet there might be a more efficient way.


One efficiency issue is that almost 90% of the os.urandom output gets
discarded. The other is more generic so I thought I'd mention it:

ret = ret + c

builds up a new string one character longer than the old value of ret,
then assigns ret to the new string. That is, the first time through
the loop (when ret is empty) it builds a 1-char string, the next time
it builds a 2-char string, etc. The total number of characters copied
around is approx 1+2+3+...+n where n is the final length, so it is
O(n**2). If n is very large (not the case for something like a password)
this gets expensive.

The usual Python idiom for building up a string in approx linear time
is:

def cstring(n):
ret = []
while (something):
ret.append(generate_another_character())
return ''.join(ret)

Python lists have a special efficiency hack so that ret.append doesn't
copy the whole list around, but rather, allocates space in bigger
chunks so that appending usually takes constant time. I don't think
this is part of the official specification but it's deeply ingrained
in Python culture and all kinds of Python code relies on it.

Another approach is to use Python's StringIO class (like Java
StringBuffer objects), but that's never been popular.
Mar 7 '06 #19
Paul Rubin wrote:
The usual Python idiom for building up a string in approx linear time
is:

def cstring(n):
ret = []
while (something):
ret.append(generate_another_character())
return ''.join(ret)

Python lists have a special efficiency hack so that ret.append doesn't
copy the whole list around, but rather, allocates space in bigger
chunks so that appending usually takes constant time.


in 2.4 and later, += on strings does the operation in place when
possible. this means that += is often faster than append/join.

</F>

Mar 7 '06 #20
I've actually done the tests on this one, it's actually faster to use
the += than a list, odd as it may sound. I ran into this one a while
back. The best way to do it is to build an array from scratch, fill the
array, and then join it, but I didn't have time to do it that way...

Mar 7 '06 #21
On Tue, 07 Mar 2006 22:32:04 +0100, Fredrik Lundh wrote:
Python lists have a special efficiency hack so that ret.append doesn't
copy the whole list around, but rather, allocates space in bigger
chunks so that appending usually takes constant time.


in 2.4 and later, += on strings does the operation in place when
possible. this means that += is often faster than append/join.


As much as we all love optimizations, I'm unhappy about this one. It used
to be a real simple rule: to append lots of strings, use append/join. That
worked for any Python you used.

But now code that runs really fast in CPython 2.4 will run like a dog in
Jython or CPython 2.3. Python's implementation independence is weakened.

Worse, because nobody really knows what "often" means (or at least, those
who know haven't said) a conscientious Python developer who wants fast
performance now has to measure all his string appending code using both
idioms to be sure that *this particular case* is/isn't one of the "often".

Is there some heuristic for telling when CPython can do the in-place
appending, and when it can't? If we were talking about a tiny (1% say)
performance penalty for getting it wrong, then it wouldn't matter, but the
penalty for using += when the optimization doesn't apply is severe.
--
Steven.

Mar 7 '06 #22
"Tuvas" <tu*****@gmail.com> writes:
I've actually done the tests on this one, it's actually faster to use
the += than a list, odd as it may sound.


Frederik explained the reason; there's an optimization in Python 2.4
that I'd forgotten about, for that specific case. It's not in earlier
versions. It's a bit fragile in 2.4:

a = ''
for x in something:
a += g(x)

is fast, but if a is aliased, Python can't do the optimization, so

a = ''
b = a
for x in something:
a += g(x)

is slow. Figuring out which case to use relies on CPython's reference
counting storage allocator (the interpreter keeps track of how many
pointers there are to any given object) and so the optimization may
not be feasible at all in other implementations which use different
storage allocation strategies (e.g. Lisp-style garbage collection).

All in all I think it's best to use a completely different approach
(something like StringBuffer) but my effort to start a movement here
on clpy a couple months ago didn't get anywhere.
Mar 7 '06 #23
Paul Rubin wrote:
"Tuvas" <tu*****@gmail.com> writes:
I've actually done the tests on this one, it's actually faster to use
the += than a list, odd as it may sound.

Frederik explained the reason; there's an optimization in Python 2.4
that I'd forgotten about, for that specific case. It's not in earlier
versions. It's a bit fragile in 2.4:

a = ''
for x in something:
a += g(x)

is fast, but if a is aliased, Python can't do the optimization, so

a = ''
b = a
for x in something:
a += g(x)

is slow.


Is this really true? After the first time through the loop, 'a' won't be
aliased any more since strings are immutable. After that the loops
should be equivalent. I tried this out to see if I could see a timing
difference, in case I was missing something, with Python 2.4.1, the
following two snippets timed essentially the same for N up to 2**20 (I
didn't try any higher):

def concat1():
a = ''
for x in ' '*N:
a += x
return a

def concat2():
a = ''
b = a
for x in ' '*N:
a += x
return a

Regards,
-tim
Figuring out which case to use relies on CPython's reference
counting storage allocator (the interpreter keeps track of how many
pointers there are to any given object) and so the optimization may
not be feasible at all in other implementations which use different
storage allocation strategies (e.g. Lisp-style garbage collection).

All in all I think it's best to use a completely different approach
(something like StringBuffer) but my effort to start a movement here
on clpy a couple months ago didn't get anywhere.


Mar 8 '06 #24
Tim Hochberg <ti**********@ieee.org> writes:
is fast, but if a is aliased, Python can't do the optimization, so
Is this really true? After the first time through the loop, 'a' won't
be aliased any more since strings are immutable.


Hmm, ok, there was some previous discussion of this problem and I
guess I mis-remembered it. Thanks. I think there is still a fairly
natural case where the optimization doesn't work. Anyone know?
Mar 8 '06 #25

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Nicholas Geraldi | last post by:
Im looking for a decent random number generator. Im looking to make a large number of random numbers (100 or so, if not more) in a short period of time (as fast as possible). the function i was...
21
by: Marc Dansereau | last post by:
Hi all I am new to this forum and to the c programming language. If I understand, the random() function in C return numbers that follow a uniform distribution U(0,1). Can somebody know how to...
5
by: cvnweb | last post by:
I am trying to generate 2 random numbers that are diffrent, in order to add them to existing numbers to generate numbers that start out the same, but are randomly added and subtracted so that they...
104
by: fieldfallow | last post by:
Hello all, Is there a function in the standard C library which returns a prime number which is also pseudo-random? Assuming there isn't, as it appears from the docs that I have, is there a...
12
by: Jim Michaels | last post by:
I need to generate 2 random numbers in rapid sequence from either PHP or mysql. I have not been able to do either. I get the same number back several times from PHP's mt_rand() and from mysql's...
21
by: chico_yallin | last post by:
I just wana make a random id number based on4 digits-for examples?? Thanks in Advance Ch.Yallin
13
by: Peter Oliphant | last post by:
I would like to be able to create a random number generator that produces evenly distributed random numbers up to given number. For example, I would like to pick a random number less than 100000,...
6
by: badcrusher10 | last post by:
Hello. I'm having trouble figuring out what to do and how to do.. could someone explain to me what I need to do in order to work? THIS IS WHAT I NEED TO DO: Professor Snoop wants a program...
24
by: pereges | last post by:
I need to generate two uniform random numbers between 0 and 1 in C ? How to do it ? I looked into rand function where you need to #define RAND_MAX as 1 but will this rand function give me ...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.