one-time_pad.sf 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 20 Novermber 2016
  5. # https://github.com/trizen
  6. # One-time pad symmetric encryption, where the key is pseudo-randomly generated from a given seed.
  7. # See also:
  8. # https://en.wikipedia.org/wiki/One-time_pad
  9. define READ_SIZE = (2 * 1024**2) # 2 MB
  10. func usage(err=nil) {
  11. if (defined(err)) {
  12. STDERR.say("\n[ERROR]: #{err}\n")
  13. }
  14. var name = File(__MAIN__).base
  15. print <<"USAGE"
  16. usage: #{name} [seed] [<input] [>output]
  17. example:
  18. #{name} 42 < original.txt > encrypted.dat
  19. #{name} 42 < encrypted.dat > decrypted.txt
  20. USAGE
  21. Sys.exit(1)
  22. }
  23. func encrypt(in_fh, out_fh, seed) {
  24. in_fh.binmode(':raw')
  25. out_fh.binmode(':raw')
  26. seed.iseed
  27. loop {
  28. var len = in_fh.read(\var chunk, READ_SIZE)
  29. var key = len.of { 255.irand }.pack('C*')
  30. out_fh.print(chunk ^ key)
  31. len == READ_SIZE || break
  32. }
  33. return true
  34. }
  35. var seed = Num(ARGV[0] \\ usage("No seed has been specified!"))
  36. encrypt(in_fh: STDIN, out_fh: STDOUT, seed: seed)