Skip to content

Commit

Permalink
rewrite randump more nicely with streams and a single encode string
Browse files Browse the repository at this point in the history
  • Loading branch information
Ali Clark committed Sep 8, 2012
1 parent fb9e6c7 commit 9cb917f
Showing 1 changed file with 92 additions and 42 deletions.
134 changes: 92 additions & 42 deletions randump.py
@@ -1,64 +1,114 @@
#!/usr/bin/python

import sys
import argparse

def base95(f, c, n, p):
s = ''

if p:
pc = ' '
else:
pc = ''
from __future__ import print_function

for i in range(n):
while True:
d = f.read((c - len(s)) * 3) # discard roughly 2/3
s += ''.join(filter(lambda x: (ord(x) >= ord(' ')) and (ord(x) <= ord('~')), d))

if len(s) >= c:
print ''.join(map(lambda x: pc + x, s[:c]))
s = s[c:]
import sys
# TODO: use more widely available alternative eg. getopt
#import argparse
import math

rand_stream = None

def xrand_stream_nb(b):
global rand_stream

savedn = 0
savedv = 0
x = None
y = 0
mask = (2 ** b) - 1

while True:
while savedn >= b:
y = savedv & mask
savedv >>= b
savedn -= b
yield y

if rand_stream == None:
rand_stream = open('/dev/random', 'rb')

try:
x = rand_stream.read(int(math.ceil((b - savedn) / 8.)))
except:
x = ''

if len(x) == 0:
try:
rand_stream.close()
finally:
rand_stream = None
raise EOFError('EOS')

while len(x) >= 1:
savedv <<= 8
savedv |= ord(x[0])
savedn += 8
x = x[1:]

def xrand_stream_n(l, t=None):
if t == None:
t = l
l = 0

if t <= l:
return

n = t - l
i = 0
while 2**i < n:
i += 1

s = xrand_stream_nb(i)
for x in s:
if x < n:
yield x + l

def base(b, c, n=1, p=False):
txt = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/!\"#$%&'()*,-.:;<=>?@[\\]^_`{|}~ "
s = xrand_stream_n(b)
pc = ' ' if p else ''
for i in xrange(n):
for j in xrange(c):
try:
sys.stdout.write(pc + txt[s.next()])
sys.stdout.flush()
except:
break

def base64(f, c, n, p):
chars = ['+', '/']
for i in range(26):
chars.append(chr(ord('a') + i))
chars.append(chr(ord('A') + i))
for i in range(10):
chars.append(chr(ord('0') + i))
sys.stdout.write('\n')
sys.stdout.flush()

if p:
pc = ' '
else:
pc = ''

for i in range(n):
print ''.join(map(lambda x: pc + chars[ord(x) & 63], f.read(c)))
class mkargs(object):
def __init__(self):
self.pad = False
self.bytes = 48 #32
self.lines = 1
#self.base = 64
self.base = 95

def main():
"""
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--pad', action='store_true', default=False)
parser.add_argument('-c', '--bytes', type=int, default=12)
parser.add_argument('-n', '--lines', type=int, default=1)
parser.add_argument('-b', '--base', type=int, default=95)
args = parser.parse_args()
"""

if args.base != 95 and args.base != 64:
print 'unknown base, use 64 or 95 (default)'
sys.exit(1)

f = open('/dev/random', 'rb')
args = mkargs()

if args.base == 95:
base95(f, args.bytes, args.lines, args.pad)
if args.base < 0:
print('minimum base is 0')
sys.exit(1)

if args.base == 64:
base64(f, args.bytes, args.lines, args.pad)
if args.base > 95:
print('maximum base is 95')
sys.exit(1)

f.close()
base(args.base, args.bytes, args.lines, args.pad)

if __name__ == '__main__':
main()

0 comments on commit 9cb917f

Please sign in to comment.