0

My company has asked me to develop a 4-byte random hexadecimal generator for some security hardware we have, however I am new to this sort of thing. (To clarify, each code consists of 4 hexadecimal digits).

We currently have a list of 124 hexadecimals that are in use and I need to be able to not repeat those hexadecimals as well as ones that will be generated with this program. I have developed a GUI and a generator, I just need help making sure it never repeats.

This is what I have so far:

# random hexadecimal generator engine 
text = "" 

for i in range(4): 
    rand = random.choice('0123456789abcdef') 
    text = text + rand 
    print(text) 

# creating the window 
root = Tk() # GUI window 
root.title("Hex Generator") 
root.geometry("250x150") 
app = Frame(root) 
app.grid() 
label = Label(app, text="Click to generate a Hexadecimal") 
button1 = Button(app, text="Generate") 
label.grid() 
button1.grid() 
label1 = Label(app, text=text) 
label1.grid() 

# kicking off event loop 
root.mainloop()
8
  • 5
    Put the code into the question, not into an unreadable comment. Commented Jan 30, 2017 at 14:10
  • As Stefan said, you should put code in your question itself, in a code block to preserve formatting. Multiline Python code is almost useless in a comment. However, we don't need to see that Tkinter stuff, it's irrelevant to your question about generating unique random numbers. Commented Jan 30, 2017 at 14:56
  • Do you want 4 bytes, which would be 8 hex digits? The code you posted only generates 4 hex digits, which is 2 bytes, so there are only 2**16 == 65536 different combinations. That doesn't sound very secure... Commented Jan 30, 2017 at 14:58
  • 1
    How big is that list of hexadecimals that are already in use? I assume this random number generator doesn't need to be of cryptographic strength, otherwise your company would be deploying a professional solution, not getting someone who knows next to nothing about crypto to write it. The first rule of crypto is "Never roll your own crypto!" Commented Jan 30, 2017 at 15:08
  • But having said that, there is an efficient way to do what you want, using the techniques of format-preserving encryption. I can post some code the illustrates the process, but you certainly shouldn't use my code if security is an issue. Commented Jan 30, 2017 at 15:08

1 Answer 1

2

Your question asks about a 4-byte random hexadecimal generator, but in the comments you clarify that you only want 4 hex digits, which means there are only 2**16 combinations. That makes the problem rather easy: we just create a list of all 65,536 combinations and shuffle it, and then we can simply iterate over that shuffled list. To save a little time & RAM I create a list of integers & just convert the integers to hex strings as needed.

The fact that you've got a list of 124 codes that are already in use adds a little bit of complexity, but we can handle that by putting those codes into a set; we can easily test the generated codes to see if they're in the used set.

Obviously, we want to be able to run the program multiple times, so we save the index number of the shuffled list into a text file. This is simpler and more efficient than storing each number that we generate into the used set.

We also need the randomization to be consistent, so we need to supply a seed to the random number generator.

Here's some Python 3 code. It can be adapted to run on Python 2 (by changing FileNotFoundError to IOError), but you cannot switch versions between runs because the sequence of random numbers generated by Python 2 will not be the same as that generated by Python 3

from random import seed, shuffle

passphrase = 'My secret passphrase'
seed(passphrase)

# Codes that were already in use. 
# This list could be read from a file instead of being embedded in the script 
used = '''\
2b2d
40a7
c257
d929
c252
5805
2936
8b20
'''

# Convert to a set of strings
used = set(used.splitlines())

# The index of the next number to generate is stored in this file
fname = 'nextindex.txt'

try:
    with open(fname) as f:
        idx = int(f.read())
except FileNotFoundError:
    idx = 0

print('Using index', idx)

allnums = list(range(0x10000))
shuffle(allnums)

#Search for the next code that's not in the `used` set
while True:
    hexcode = format(allnums[idx], '04x')
    idx += 1
    if hexcode not in used:
        print('Code:', hexcode)
        break

# Save the next index
with open(fname, 'w') as f:
    print('Saving index', idx)
    f.write(str(idx))

output from 3 runs

Using index 0
Code: d0fc
Saving index 1

Using index 1
Code: d7e9
Saving index 3

Using index 3
Code: fc42
Saving index 4

As you can see, index 2 gets skipped, that's because it corresponds to a code in the used set.

Sign up to request clarification or add additional context in comments.

8 Comments

Wow, hey thank you so much. That helps out a ton! I greatly appreciate it. Is there any resources in particular you recommend for me to learn so I can someday get to your level?
Forgive me I will have to ask a dumb question, but it's only because I don't know. For this to be ready for deployment, I will need to create a text file and import that file in the code for it to be read, checked to see if theres any duplicates, and when it generates the hexadecimal, write to that same text file correct?
@G.Rose All you need to do is create the list of hex codes that have already been used, and either paste it into the script, or read it from a file. You don't need to keep track of the new codes that get generated, the script does that by saving idx. It will never generate a previously used number, but it will fail with IndexError: list index out of range after it has used up all the numbers in allnums.
@G.Rose As for resources on learning to write better Python, there are a few listed at What tutorial should I read?. And of course you can learn a lot by studying the code of good answers here on SO. But the main thing is to write lots of code! Write little programs that experiment with features you don't quite understand, and when you get stuck, try to find out what's gone wrong by searching on SO. And when all else fails, ask here for help. :)
Thank you again. I genuinely appreciate all of the information. I already learned more than what my college has shown me. Have a good one :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.