Skip to main content
Code Review

Return to Answer

added 26 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" (like 15) and allow parameters (with sensible defaults) for arbitrarily chosen values (like length).

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 import itertools
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and requires either \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size) to keep track of previously drawn items.

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" (like 15) and allow parameters (with sensible defaults) for arbitrarily chosen values (like length).

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and requires either \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size) to keep track of previously drawn items.

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" (like 15) and allow parameters (with sensible defaults) for arbitrarily chosen values (like length).

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 import itertools
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and requires either \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size) to keep track of previously drawn items.

added 26 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" (like 15) and allow parameters (with sensible defaults) for arbitrarily chosen values (like length).

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and either requires either \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size) to keep track of previously drawn items.

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" and allow parameters (with sensible defaults) for arbitrarily chosen values.

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and either requires \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size).

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" (like 15) and allow parameters (with sensible defaults) for arbitrarily chosen values (like length).

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and requires either \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size) to keep track of previously drawn items.

added 15 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" and allow parameters (with sensible defaults) for arbitrarily chosen values.

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and either requires \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size).

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space significantly1 and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" and allow parameters (with sensible defaults) for arbitrarily chosen values.

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and either requires \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size).

Sampling method

(削除) sample() (削除ここまで) is the wrong kind of sampling here since it draws k random samples from the given population/alphabet without repetition. Instead you should should use choices() which allows repetition of the same items.

Normally you want as much entropy as possible in the given "space" (here: k = 15 items chosen from N = 66 Arabic digits, basic Latin letters and some punctuation). If you disallow repetitions you reduce the size of the key space (although not significantly1) and risk more (frequent) collisions at no benefit and more costly sample computation2.

Source of (pseudo-)randomness

You should also consider that the random module’s default (pseudo-)random number generator is not normally "safe". See Gaipher’s comment for a possible safe alternative.

Avoid magic numbers, allow parameters if possible

Additionally you should avoid unexplained "magic numbers" and allow parameters (with sensible defaults) for arbitrarily chosen values.

Resulting code

def generate_unique_key(length=15):
 array = # ... construct character set
 return "".join(random.choices(array, k=length))

For Python versions prior to 3.6 you can provide a simple implementations of choices() yourself:

import random
try:
 random_choices = random.choices
except AttributeError:
 def random_choices(population, *, k=1):
 return map(random.choice, itertools.repeat(population, k))

1 Key space comparison:

  • with repetition: \$N^k = 66^{15} \approx 2.0 \cdot 10^{27}\$
  • without repetition: \$\prod^{N}_{i=N-k+1} i = \frac{!N}{!(N - k)} = \frac{!66}{!(66 - 15)} \approx 3.5 \cdot 10^{26}\$

2 An optimal algorithm for random samples without repetition is more complex than one with repetition and either requires \$O(k)\$ intermediate storage or \$O(k^2)\$ runtime (with k being the sample size).

section titles
Source Link
David Foerster
  • 1.7k
  • 10
  • 20
Loading
added 270 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20
Loading
added 559 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20
Loading
added 559 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20
Loading
added 559 characters in body
Source Link
David Foerster
  • 1.7k
  • 10
  • 20
Loading
Source Link
David Foerster
  • 1.7k
  • 10
  • 20
Loading
lang-py

AltStyle によって変換されたページ (->オリジナル) /