hex_randomness_info.sf 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/ruby
  2. # Show some information about the randomness of a given hex-encoded string.
  3. # See also:
  4. # https://rosettacode.org/wiki/Entropy
  5. func entropy(bytes) {
  6. var counts = bytes.freq
  7. var len = bytes.len
  8. [0, counts.values.map {|count|
  9. var freq = count/len; freq * freq.log2 }...
  10. ]«-»
  11. }
  12. func arithmetic_mean(bytes) {
  13. Math.arithmetic_mean(bytes.map {_+1}...)
  14. }
  15. func geometric_mean(bytes) {
  16. Math.geometric_mean(bytes.map {_+1}...)
  17. }
  18. func harmonic_mean(bytes) {
  19. Math.harmonic_mean(bytes.map {_+1}...)
  20. }
  21. var hex = ARGV[0] \\ die "usage: #{__MAIN__} [hex string]\n"
  22. if (hex !~ /^[[:xdigit:]]+\z/) {
  23. die "The input must be a hexadecimal string!\n"
  24. }
  25. var ascii = hex.hex2ascii
  26. var bytes = ascii.bytes
  27. var bits = ascii.ascii2hex.hex.bits
  28. var rand_bytes = bytes.len.random_bytes
  29. var rand_bits = bits.len.of { [0,1].rand }
  30. printf(<<-"EOT",
  31. BYTE TESTS | VALUE
  32. ---------------------------------------------
  33. Entropy(bytes) : %8.4g (rand: %6.4g)
  34. A(bytes) : %8.4g (rand: %6.4g)
  35. G(bytes) : %8.4g (rand: %6.4g)
  36. H(bytes) : %8.4g (rand: %6.4g)
  37. BIT TESTS | VALUE
  38. ---------------------------------------------
  39. Entropy(bits) : %8.4g (rand: %6.4g)
  40. A(bits) : %8.4g (rand: %6.4g)
  41. G(bits) : %8.4g (rand: %6.4g)
  42. H(bits) : %8.4g (rand: %6.4g)
  43. EOT
  44. entropy(bytes), entropy(rand_bytes),
  45. arithmetic_mean(bytes), arithmetic_mean(rand_bytes),
  46. geometric_mean(bytes), geometric_mean(rand_bytes),
  47. harmonic_mean(bytes), harmonic_mean(rand_bytes),
  48. entropy(bits), entropy(rand_bits),
  49. arithmetic_mean(bits), arithmetic_mean(rand_bits),
  50. geometric_mean(bits), geometric_mean(rand_bits),
  51. harmonic_mean(bits), harmonic_mean(rand_bits)
  52. )
  53. __END__
  54. # Example:
  55. $ sidef hex_randomness_info.sf $(sidef -E 'File("/usr/bin/perl").read(:raw).ascii2hex.say')
  56. BYTE TESTS | VALUE
  57. ---------------------------------------------
  58. Entropy(bytes) : 1.947 (rand: 7.987)
  59. A(bytes) : 17.18 (rand: 129.2)
  60. G(bytes) : 2.083 (rand: 96.3)
  61. H(bytes) : 1.212 (rand: 42.71)
  62. BIT TESTS | VALUE
  63. ---------------------------------------------
  64. Entropy(bits) : 0.4062 (rand: 1)
  65. A(bits) : 1.081 (rand: 1.501)
  66. G(bits) : 1.058 (rand: 1.415)
  67. H(bits) : 1.042 (rand: 1.334)