You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.9 KiB

  1. #!/usr/bin/perl
  2. #
  3. # Intent:
  4. # re-usable routines ...
  5. #
  6. # Note:
  7. # This work has been done during my time at Doctor I·T
  8. #
  9. # -- Copyright drit, 2021 --
  10. #
  11. package misc;
  12. require Exporter;
  13. @ISA = qw(Exporter);
  14. # Subs we export by default.
  15. @EXPORT = qw();
  16. # Subs we will export if asked.
  17. #@EXPORT_OK = qw(nickname);
  18. @EXPORT_OK = grep { $_ !~ m/^_/ && defined &$_; } keys %{__PACKAGE__ . '::'};
  19. use strict;
  20. # The "use vars" and "$VERSION" statements seem to be required.
  21. use vars qw/$dbug $VERSION/;
  22. # ----------------------------------------------------
  23. our $VERSION = sprintf "%d.%02d", q$Revision: 0.0 $ =~ /: (\d+)\.(\d+)/;
  24. my ($State) = q$State: Exp $ =~ /: (\w+)/; our $dbug = ($State eq 'dbug')?1:0;
  25. # ----------------------------------------------------
  26. $VERSION = &version(__FILE__) unless ($VERSION ne '0.00');
  27. # -----------------------------------------------------------------------
  28. sub jsonify {
  29. use JSON qw(encode_json);
  30. my $obj = shift;
  31. my $json = encode_json( $obj ); # /!\ keys are note sorted !
  32. return $json;
  33. }
  34. sub yamlify {
  35. use YAML::Syck qw(Dump);
  36. my $obj = shift;
  37. my $yml = Dump($obj);
  38. return $yml;
  39. }
  40. # -----------------------------------------------------------------------
  41. sub khash { # keyed hash
  42. use Crypt::Digest qw();
  43. my $alg = shift;
  44. my $data = join'',@_;
  45. my $msg = Crypt::Digest->new($alg) or die $!;
  46. $msg->add($data);
  47. my $hash = $msg->digest();
  48. return $hash;
  49. }
  50. # -----------------------------------------------------------------------
  51. sub version {
  52. #y ($atime,$mtime,$ctime) = (lstat($_[0]))[8,9,10];
  53. my @times = sort { $a <=> $b } (lstat($_[0]))[9,10]; # ctime,mtime
  54. my $vtime = $times[-1]; # biggest time...
  55. my $version = &rev($vtime);
  56. if (wantarray) {
  57. my $shk = &get_shake(160,$_[0]);
  58. print "$_[0] : shk:$shk\n" if $dbug;
  59. my $pn = unpack('n',substr($shk,-4)); # 16-bit
  60. my $build = &word($pn);
  61. return ($version, $build);
  62. } else {
  63. return sprintf '%g',$version;
  64. }
  65. }
  66. # -----------------------------------------------------------------------
  67. sub rev {
  68. my ($sec,$min,$hour,$mday,$mon,$yy,$wday,$yday) = (localtime($_[0]))[0..7];
  69. my $rweek=($yday+&fdow($_[0]))/7;
  70. my $rev_id = int($rweek) * 4;
  71. my $low_id = int(($wday+($hour/24)+$min/(24*60))*4/7);
  72. my $revision = ($rev_id + $low_id) / 100;
  73. return (wantarray) ? ($rev_id,$low_id) : $revision;
  74. }
  75. # -----------------------------------------------------------------------
  76. sub fdow {
  77. my $tic = shift;
  78. use Time::Local qw(timelocal);
  79. ## 0 1 2 3 4 5 6 7
  80. #y ($sec,$min,$hour,$day,$mon,$year,$wday,$yday)
  81. my $year = (localtime($tic))[5]; my $yr4 = 1900 + $year ;
  82. my $first = timelocal(0,0,0,1,0,$yr4);
  83. our $fdow = (localtime($first))[6];
  84. #printf "1st: %s -> fdow: %s\n",&hdate($first),$fdow;
  85. return $fdow;
  86. }
  87. # -----------------------------------------------------------------------
  88. sub get_shake { # use shake 256 because of ipfs' minimal length of 20Bytes
  89. use Crypt::Digest::SHAKE;
  90. my $len = shift;
  91. local *F; open F,$_[0] or do { warn qq{"$_[0]": $!}; return undef };
  92. #binmode F unless $_[0] =~ m/\.txt/;
  93. my $msg = Crypt::Digest::SHAKE->new(256);
  94. $msg->addfile(*F);
  95. my $digest = $msg->done(($len+7)/8);
  96. return $digest;
  97. }
  98. # -----------------------------------------------------------------------
  99. sub word { # 20^4 * 6^3 words (25bit worth of data ...)
  100. use integer;
  101. my $n = $_[0];
  102. my $vo = [qw ( a e i o u y )]; # 6
  103. my $cs = [qw ( b c d f g h j k l m n p q r s t v w x z )]; # 20
  104. my $str = '';
  105. if (1 && $n < 26) {
  106. $str = chr(ord('a') +$n%26);
  107. } else {
  108. $n -= 6;
  109. while ($n >= 20) {
  110. my $c = $n % 20;
  111. $n /= 20;
  112. $str .= $cs->[$c];
  113. #print "cs: $n -> $c -> $str\n";
  114. $c = $n % 6;
  115. $n /= 6;
  116. $str .= $vo->[$c];
  117. #print "vo: $n -> $c -> $str\n";
  118. }
  119. if ($n > 0) {
  120. $str .= $cs->[$n];
  121. }
  122. return $str;
  123. }
  124. }
  125. # -----------------------------------------------------------------------
  126. 1; # $Source: /my/perl/modules/misc.pm $