one-time_pad.pl 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 13 November 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. #---------------------------------------------------
  10. # !!! WARNING !!!
  11. #---------------------------------------------------
  12. # This program is just a proof-of-concept.
  13. # Do NOT use this program to encrypt sensitive data!
  14. #---------------------------------------------------
  15. use 5.010;
  16. use strict;
  17. use warnings;
  18. use Getopt::Std qw(getopts);
  19. my %opts;
  20. getopts('s:h', \%opts);
  21. use constant {
  22. READ_SIZE => 2 * 1024**2, # 2 MB
  23. };
  24. sub usage {
  25. warn "\n[ERROR]: ", @_, "\n\n" if @_;
  26. print <<"USAGE";
  27. usage: $0 [options] [<input] [>output]
  28. options:
  29. -s SEED : random seed
  30. example:
  31. $0 -s 42 < input.txt > output.dat
  32. USAGE
  33. exit 1;
  34. }
  35. $opts{h} && usage();
  36. encode_file(
  37. in_fh => \*STDIN,
  38. out_fh => \*STDOUT,
  39. seed => defined($opts{s}) ? $opts{s} : usage("No seed specified!"),
  40. );
  41. sub generate_key {
  42. my ($length) = @_;
  43. pack('C*', map { int(rand(256)) } 1 .. $length);
  44. }
  45. sub encode_file {
  46. my %args = @_;
  47. srand($args{seed});
  48. while (1) {
  49. my $len = read($args{in_fh}, my ($chunk), READ_SIZE);
  50. my $key = generate_key($len);
  51. print {$args{out_fh}} $chunk ^ $key;
  52. last if $len != READ_SIZE;
  53. }
  54. return 1;
  55. }