Generating non-repeating random numbers in Python

前端 未结 17 1757
粉色の甜心
粉色の甜心 2020-11-30 19:56

Ok this is one of those trickier than it sounds questions so I\'m turning to stack overflow because I can\'t think of a good answer. Here is what I want: I need Python to ge

17条回答
  •  情歌与酒
    2020-11-30 20:48

    You could use Format-Preserving Encryption to encrypt a counter. Your counter just goes from 0 upwards, and the encryption uses a key of your choice to turn it into a seemingly random value of whatever radix and width you want.

    Block ciphers normally have a fixed block size of e.g. 64 or 128 bits. But Format-Preserving Encryption allows you to take a standard cipher like AES and make a smaller-width cipher, of whatever radix and width you want (e.g. radix 10, width 9 for the parameters of the question), with an algorithm which is still cryptographically robust.

    It is guaranteed to never have collisions (because cryptographic algorithms create a 1:1 mapping). It is also reversible (a 2-way mapping), so you can take the resulting number and get back to the counter value you started with.

    AES-FFX is one proposed standard method to achieve this.

    I've experimented with some basic Python code for AES-FFX--see Python code here (but note that it doesn't fully comply with the AES-FFX specification). It can e.g. encrypt a counter to a random-looking 7-digit decimal number. E.g.:

    0000000   0731134
    0000001   6161064
    0000002   8899846
    0000003   9575678
    0000004   3030773
    0000005   2748859
    0000006   5127539
    0000007   1372978
    0000008   3830458
    0000009   7628602
    0000010   6643859
    0000011   2563651
    0000012   9522955
    0000013   9286113
    0000014   5543492
    0000015   3230955
    ...       ...
    

    For another example in Python, using another non-AES-FFX (I think) method, see this blog post "How to Generate an Account Number" which does FPE using a Feistel cipher. It generates numbers from 0 to 2^32-1.

提交回复
热议问题