cvsuser     05/03/22 02:15:44

  Modified:    .        MANIFEST
  Added:       examples/assembly md5sum.imc
               runtime/parrot/library/Digest MD5.imc
               t/library md5.t
  Log:
  add Nick's md5 code
  
  * mostly original except:
    * don't splice the buffer
    * use integer array
    * overall speedup of a factor of 25 :)
  * and cosmetics:
    * converted to library
    * minor whitespace change
  
  Courtesy of Nick Glencross <[EMAIL PROTECTED]>
  
  Revision  Changes    Path
  1.853     +3 -0      parrot/MANIFEST
  
  Index: MANIFEST
  ===================================================================
  RCS file: /cvs/public/parrot/MANIFEST,v
  retrieving revision 1.852
  retrieving revision 1.853
  diff -u -r1.852 -r1.853
  --- MANIFEST  21 Mar 2005 19:22:26 -0000      1.852
  +++ MANIFEST  22 Mar 2005 10:15:34 -0000      1.853
  @@ -445,6 +445,7 @@
   examples/assembly/local_label.pasm                [main]doc
   examples/assembly/mandel.imc                      [main]doc
   examples/assembly/mandel.pasm                     [main]doc
  +examples/assembly/md5sum.imc                      [main]doc
   examples/assembly/mops.pasm                       [main]doc
   examples/assembly/mops_p.pasm                     [main]doc
   examples/assembly/nanoforth.pasm                  [main]doc
  @@ -2673,6 +2674,7 @@
   runtime/parrot/library/Data/Dumper.imc            [library]
   runtime/parrot/library/Data/Dumper/Base.imc       [library]
   runtime/parrot/library/Data/Dumper/Default.imc    [library]
  +runtime/parrot/library/Digest/MD5.imc             [library]
   runtime/parrot/library/PGE/Class.pir              [library]
   runtime/parrot/library/PGE/RegCounter.pir         [library]
   runtime/parrot/library/PGE.pir                    [library]
  @@ -2940,6 +2942,7 @@
   t/pmc/undef.t                                     []
   t/library/dumper.t                                []
   t/library/getopt_long.t                           []
  +t/library/md5.t                                   []
   t/library/parrotlib.t                             []
   t/library/perlhist.txt                            []
   t/library/pge.t                                   []
  
  
  
  1.1                  parrot/examples/assembly/md5sum.imc
  
  Index: md5sum.imc
  ===================================================================
  # Parrot md5sum; Nick Glencross <[EMAIL PROTECTED]>
  #
  # Based on md5.c, from md5sum
  #           written by Ulrich Drepper <[EMAIL PROTECTED]>, 1995.
  
  =head1 NAME
  
  examples/assembly/md5sum.imc - calculate MD5 checksums
  
  =head1 SYNOPSIS
  
      % ./parrot examples/assembly/md5sum.imc filename [filename ...]
  
  =head1 DESCRIPTION
  
  Behave very much like md5sum(1).
  
  =cut
  
  ###########################################################################
  
  
  # Main Harness to show that it works
  
  .sub _main @MAIN
      .param pmc args
  
      .local int   size
      load_bytecode "library/Digest/MD5.imc"
      # Argument count
      $I0 = args
      $I0 = $I0 - 1
      if $I0 > 0 goto has_args
      $S0 = args[0]
      printerr "(parrot) "
      printerr $S0
      printerr " filename [filename ...]\n"
      exit 1
  
  has_args:
  
      $I1 = 1
  
  next_iter:
  
      if $I1 > $I0 goto iter_done
      $S0 = args[$I1]
      .include "stat.pasm"
      # get size of file
      stat size, $S0, .STAT_FILESIZE
      open $P0, $S0, "<"
      defined $I2, $P0
      if $I2 goto found
      printerr $S0
      printerr ": Cannot find\n"
      goto iter_cont
  found:
      read $S1, $P0, size
      close $P0
  
      $I2 = length $S1
      if $I2 == size goto size_ok
  
      printerr $S0
      printerr ": size mismatch\n"
      goto iter_cont
  
  size_ok:
  
      $P0 = _md5sum ($S1)
      _md5_print ($P0)
      print "\t"
      print $S0
      print "\n"
  
  iter_cont:
  
      $I1 = $I1 + 1
      goto next_iter
  
  iter_done:
  
       end
  .end
  
  
  
  
  1.1                  parrot/runtime/parrot/library/Digest/MD5.imc
  
  Index: MD5.imc
  ===================================================================
  # Parrot md5sum; Nick Glencross <[EMAIL PROTECTED]>
  #
  # Based on md5.c, from md5sum
  #           written by Ulrich Drepper <[EMAIL PROTECTED]>, 1995.
  
  =head1 NAME
  
  MD5.imc - calculate MD5 checksums
  
  =head1 SYNOPSIS
  
    load_bytecode "library/Digest/MD5.imc"
    $P0 = _md5sum("foo")
    _md5_print($P0)
  
  =head1 DESCRIPTION
  
  This is a pure Parrot MD5 hash routine. Therefore you should run it
  with the JIT core if possible.
  
  =head1 SUBROUTINES
  
  =head2 _md5sum
  
  Pass in a string, returns an Integer array with the result
  
  =head2 _md5_print
  
  Pass it the Integer array to print the checksum.
  
  =head1 BUGS
  
  Only tested so far on i386.
  
  =over 4
  
  =item * Might work on 64 bit platforms
  
  =item * Might not work on big endian systems
  
  =back
  
  =cut
  
  ####################################
  # export function entries to globals
  
  .sub onload @LOAD
      .local pmc f
      f = find_global "Digest", "_md5sum"
      global "_md5sum" = f
      f = find_global "Digest", "_md5_print"
      global "_md5_print" = f
  .end
  
  .include "library/config.imc"
  
  ###########################################################################
  # Main entry point
  
  .namespace ["Digest"]
  
  .sub _md5sum
      .param string str
  
      $P0 = _config()
  
      $I0 = $P0["intsize"]
      if $I0 == 4 goto is_4byte_word
  
      printerr "This doesn't seem to be a 32 bit processor: "
      printerr "Please verify the MD5 checksum\n"
  
  is_4byte_word:
  
      .local int endian
      endian = $P0["bigendian"]
      unless endian goto is_little_endian
      printerr "This appears to be a big endian processor: "
      printerr "Please verify the MD5 checksum\n"
  
  is_little_endian:
  
      .local pmc buffer, context
      buffer = new FixedIntegerArray
  
      context = new FixedIntegerArray
      context = 4
  
      _md5_create_buffer (str, buffer, endian)
  
      # _print_buffer (buffer, 8)
  
      _md5_init (context)
      _md5_process_buffer (context, buffer)
  
      .return(context)
  .end
  
  
  ###########################################################################
  # Low-level macros used in MD5
  
  # A parrot rol instruction might be good (as it can often be JIT'd)
  .macro rol (x,n,  out)
      .out = .x << .n
      $I1000 = 32 - .n
      $I1000 = .x >>> $I1000
      $I1000 = $I1000 & 0xffffffff
      .out |= $I1000
  .endm
  
  .macro FF (b,c,d)
      tmp = .c ~ .d
      tmp = .b & tmp
      tmp = .d ~ tmp
  .endm
  
  .macro FH (b,c,d)
      tmp = .b ~ .c
      tmp = tmp ~ .d
  .endm
  
  .macro FI (b,c,d)
      tmp = ~.d
      tmp = .b | tmp
      tmp = .c ~ tmp
  .endm
  
  ###########################################################################
  # Higher level MD5 operations
  
  .macro common (a, b, k, s, T)
      .a += tmp
      .a += .T
      $I99 = .k + idx
      tmp = buffer[$I99]
      .a += tmp
      .rol (.a, .s, tmp)
      .a = .b + tmp
  .endm
  
  .macro OP1 (aa,bb,cc,dd, kk, ss, TT)
      .FF (.bb,.cc,.dd)
      .common (.aa, .bb, .kk, .ss, .TT)
  .endm
  
  .macro OP2 (aa,bb,cc,dd, kk, ss, TT)
      .FF (.dd,.bb,.cc)
      .common (.aa, .bb, .kk, .ss, .TT)
  .endm
  
  .macro OP3 (aa,bb,cc,dd, kk, ss, TT)
      .FH (.bb,.cc,.dd)
      .common (.aa, .bb, .kk, .ss, .TT)
  .endm
  
  .macro OP4 (aa,bb,cc,dd, kk, ss, TT)
      .FI (.bb,.cc,.dd)
      .common (.aa, .bb, .kk, .ss, .TT)
  .endm
  
  ###########################################################################
  
  # Swap the bytes which make up a word
  
  .macro swap (w)
       $I10 = .w & 0x000000ff
       $I11 = .w & 0x0000ff00
       $I12 = .w & 0x00ff0000
       $I13 = .w & 0xff000000
  
       $I10 = $I10 <<  24
       $I11 = $I11 <<  8
       $I12 = $I12 >>> 8
       $I13 = $I13 >>> 24
  
       $I10 = $I10 | $I11
       $I10 = $I10 | $I12
       .w   = $I10 | $I13
  
       # For 64-bit architectures
       .w   = .w & 0xffffffff
  
  .endm
  
  ###########################################################################
  
  # Set the initial MD5 constants
  
  .sub _md5_init
      .param pmc context
  
      # Initial MD5 constants
      context[0] = 0x67452301
      context[1] = 0xefcdab89
      context[2] = 0x98badcfe
      context[3] = 0x10325476
  
  .end
  
  ###########################################################################
  
  # Create a buffer from the requested buffer
  
  .sub _md5_create_buffer
      .param string str
      .param pmc  buffer
      .param int endian
  
      .local int counter
      .local int subcounter
      .local int slow_counter
  
      .local int word, len
  
       len = length str
  
       $I1 = len - 1
  
       # Work out how many words to allocate
       .local int words
       words = len + 8
       words = words | 63
       words = words + 1
       words = words / 4
  
       buffer = words
  
       word         = 0
       counter      = 0
       subcounter   = 0
       slow_counter = 0
  
  md5_create_buffer_loop:
  
       $I5 = counter + subcounter
  
       if $I5 > len goto md5_create_buffer_break
  
       # MD5 pad character, which goes last
       $I4 = 0x80
  
       if $I5 > $I1 goto string_char
       $I4 = ord str, $I5
  
  string_char:
  
       word = word << 8
       word = word | $I4
  
       inc subcounter
       if subcounter != 4 goto md5_create_buffer_loop
       if endian goto endian_ok
         .swap (word)
  endian_ok:
  
  
       buffer[slow_counter] = word
  
       word         = 0
       counter      = counter + 4
       subcounter   = 0
       inc slow_counter
  
       goto md5_create_buffer_loop
  
  md5_create_buffer_break:
  
       # Check for a partial word
  
       if subcounter == 0 goto complete
       subcounter = 4 - subcounter
       .local int shift
       shift = 8*subcounter
       word = word << shift
       if endian goto endian_ok2
         .swap (word)
  endian_ok2:
  
       buffer[slow_counter] = word
  
  complete:
  
       # The number of bits in the string go into the last two words
  
       $I1 = len >>> 29
       words = words - 1
       buffer[words] = $I1
  
       $I0 = len << 3
       words = words - 1
       buffer[words] = $I0
  
  .end
  
  ###########################################################################
  
  .sub _md5_process_buffer
      .param pmc    context
      .param pmc  buffer
  
      .local int A
      .local int B
      .local int C
      .local int D
  
      .local int A_save
      .local int B_save
      .local int C_save
      .local int D_save
  
      .local int tmp, idx, len
  
      idx = 0
      len = elements buffer
  
      A = context[0]
      B = context[1]
      C = context[2]
      D = context[3]
  
  md5_loop:
  
      A_save = A
      B_save = B
      C_save = C
      D_save = D
  
      # Round 1.
      .OP1 (A, B, C, D, 0,  7, 0xd76aa478)
      .OP1 (D, A, B, C, 1, 12, 0xe8c7b756)
      .OP1 (C, D, A, B, 2, 17, 0x242070db)
      .OP1 (B, C, D, A, 3, 22, 0xc1bdceee)
      .OP1 (A, B, C, D, 4,  7, 0xf57c0faf)
      .OP1 (D, A, B, C, 5, 12, 0x4787c62a)
      .OP1 (C, D, A, B, 6, 17, 0xa8304613)
      .OP1 (B, C, D, A, 7, 22, 0xfd469501)
      .OP1 (A, B, C, D, 8,  7, 0x698098d8)
      .OP1 (D, A, B, C, 9, 12, 0x8b44f7af)
      .OP1 (C, D, A, B, 10,17, 0xffff5bb1)
      .OP1 (B, C, D, A, 11,22, 0x895cd7be)
      .OP1 (A, B, C, D, 12, 7, 0x6b901122)
      .OP1 (D, A, B, C, 13,12, 0xfd987193)
      .OP1 (C, D, A, B, 14,17, 0xa679438e)
      .OP1 (B, C, D, A, 15,22, 0x49b40821)
  
      # Round 2.
      .OP2 (A, B, C, D,  1,  5, 0xf61e2562)
      .OP2 (D, A, B, C,  6,  9, 0xc040b340)
      .OP2 (C, D, A, B, 11, 14, 0x265e5a51)
      .OP2 (B, C, D, A,  0, 20, 0xe9b6c7aa)
      .OP2 (A, B, C, D,  5,  5, 0xd62f105d)
      .OP2 (D, A, B, C, 10,  9, 0x02441453)
      .OP2 (C, D, A, B, 15, 14, 0xd8a1e681)
      .OP2 (B, C, D, A,  4, 20, 0xe7d3fbc8)
      .OP2 (A, B, C, D,  9,  5, 0x21e1cde6)
      .OP2 (D, A, B, C, 14,  9, 0xc33707d6)
      .OP2 (C, D, A, B,  3, 14, 0xf4d50d87)
      .OP2 (B, C, D, A,  8, 20, 0x455a14ed)
      .OP2 (A, B, C, D, 13,  5, 0xa9e3e905)
      .OP2 (D, A, B, C,  2,  9, 0xfcefa3f8)
      .OP2 (C, D, A, B,  7, 14, 0x676f02d9)
      .OP2 (B, C, D, A, 12, 20, 0x8d2a4c8a)
  
      # Round 3.
      .OP3 (A, B, C, D,  5,  4, 0xfffa3942)
      .OP3 (D, A, B, C,  8, 11, 0x8771f681)
      .OP3 (C, D, A, B, 11, 16, 0x6d9d6122)
      .OP3 (B, C, D, A, 14, 23, 0xfde5380c)
      .OP3 (A, B, C, D,  1,  4, 0xa4beea44)
      .OP3 (D, A, B, C,  4, 11, 0x4bdecfa9)
      .OP3 (C, D, A, B,  7, 16, 0xf6bb4b60)
      .OP3 (B, C, D, A, 10, 23, 0xbebfbc70)
      .OP3 (A, B, C, D, 13,  4, 0x289b7ec6)
      .OP3 (D, A, B, C,  0, 11, 0xeaa127fa)
      .OP3 (C, D, A, B,  3, 16, 0xd4ef3085)
      .OP3 (B, C, D, A,  6, 23, 0x04881d05)
      .OP3 (A, B, C, D,  9,  4, 0xd9d4d039)
      .OP3 (D, A, B, C, 12, 11, 0xe6db99e5)
      .OP3 (C, D, A, B, 15, 16, 0x1fa27cf8)
      .OP3 (B, C, D, A,  2, 23, 0xc4ac5665)
  
      # Round 4.
      .OP4 (A, B, C, D,  0,  6, 0xf4292244)
      .OP4 (D, A, B, C,  7, 10, 0x432aff97)
      .OP4 (C, D, A, B, 14, 15, 0xab9423a7)
      .OP4 (B, C, D, A,  5, 21, 0xfc93a039)
      .OP4 (A, B, C, D, 12,  6, 0x655b59c3)
      .OP4 (D, A, B, C,  3, 10, 0x8f0ccc92)
      .OP4 (C, D, A, B, 10, 15, 0xffeff47d)
      .OP4 (B, C, D, A,  1, 21, 0x85845dd1)
      .OP4 (A, B, C, D,  8,  6, 0x6fa87e4f)
      .OP4 (D, A, B, C, 15, 10, 0xfe2ce6e0)
      .OP4 (C, D, A, B,  6, 15, 0xa3014314)
      .OP4 (B, C, D, A, 13, 21, 0x4e0811a1)
      .OP4 (A, B, C, D,  4,  6, 0xf7537e82)
      .OP4 (D, A, B, C, 11, 10, 0xbd3af235)
      .OP4 (C, D, A, B,  2, 15, 0x2ad7d2bb)
      .OP4 (B, C, D, A,  9, 21, 0xeb86d391)
  
      A += A_save
      B += B_save
      C += C_save
      D += D_save
  
      idx += 16
  
      if idx < len goto md5_loop
  
      context[0] = A
      context[1] = B
      context[2] = C
      context[3] = D
  
      # _print_vals (A,B,C,D)
      # print "\n"
  
  .end
  
  ###########################################################################
  
  # Print four hex values
  
  .sub _print_vals
      .param int A
      .param int B
      .param int C
      .param int D
  
      $P0 = new FixedIntegerArray
      $P0 = 4
      $P0[0] = A
      $P0[1] = B
      $P0[2] = C
      $P0[3] = D
  
      sprintf $S0, "%08lx%08lx%08lx%08lx", $P0
      print $S0
  .end
  
  ###########################################################################
  
  # Print the final checksum
  
  .sub _md5_print
      .param pmc context
  
      .local int A
      .local int B
      .local int C
      .local int D
  
      A = context[0]
      B = context[1]
      C = context[2]
      D = context[3]
  
      $P0 = _config()
  
      $I0 = $P0["bigendian"]
  
      if $I0 goto dont_swap
  
      .swap (A)
      .swap (B)
      .swap (C)
      .swap (D)
  
  dont_swap:
  
      _print_vals (A,B,C,D)
  .end
  
  ###########################################################################
  
  # For debugging
  
  .sub _print_buffer
      .param pmc buffer
      .param int word_size
  
      .local int size
  
      size = buffer
  
      .local int counter
      .local int value
  
      counter = 0
  
  print_buffer_loop:
      if counter >= size goto print_buffer_done
      value = buffer[counter]
      $S0 = _number_as_hex (value, word_size)
      print $S0
      print " | "
      counter = counter + 1
      goto print_buffer_loop
  
  print_buffer_done:
  
      print "\n"
  .end
  
  ###########################################################################
  
  # Also for debugging
  
  .sub _number_as_hex
      .param int number
      .param int word_size
  
      $P0 = new FixedIntegerArray
      $P0 = 1
      $P0[0] = number
  
      $S1 = "%0"
      $S0 = word_size
      concat $S1, $S0
      concat $S1, "lx"
  
      sprintf $S0, $S1, $P0
  
      .return($S0)
  .end
  
  
  
  1.1                  parrot/t/library/md5.t
  
  Index: md5.t
  ===================================================================
  #!perl
  
  # You can create the test results using using the command-line md5sum
  # like this:
  #
  # $ echo -n Hello World! | md5sum
  # a0f32c7d31302c1427285b1a0fcbb015  -
  
  use strict;
  use Parrot::Test tests => 3;
  
  use Parrot::Config;
  
  my $bigendian = $PConfig{bigendian};
  my $intsize   = $PConfig{intsize};
  
  SKIP: {
  
  if ($bigendian || $intsize != 4)
  {
      skip('MD5 only known to work on small endian 32 bit processors', 3)
  }
  
  
  ##############################
  # Stress IMCC and parrot using MD5 library
  
  pir_output_is(<<'CODE', <<'OUT', "Miscellaneous words");
  .sub _main
      load_bytecode "library/Digest/MD5.imc"
      $P0 = _md5sum ("Hello")
      _md5_print ($P0)
      print "\n"
  
      $P0 = _md5sum ("Goodbye")
      _md5_print ($P0)
      print "\n"
  
      $P0 = _md5sum ("Parrot")
      _md5_print ($P0)
      print "\n"
  
      $P0 = _md5sum ("Hello World!")
      _md5_print ($P0)
      print "\n"
  
      end
  .end
  CODE
  8b1a9953c4611296a827abf8c47804d7
  6fc422233a40a75a1f028e11c3cd1140
  e7cb1e977e896954fec46d2ea7832072
  ed076287532e86365e841e92bfc50d8c
  OUT
  
  pir_output_is(<<'CODE', <<'OUT', "Funny chars");
  .sub _main
      load_bytecode "library/Digest/MD5.imc"
      $P0 = _md5sum ("\n\n\n\n\t")
      _md5_print ($P0)
      print "\n"
      end
  .end
  CODE
  b66434493525523b4393ce0d1f2425d7
  OUT
  
  
  my $code = join
      ("\n\n",
       map
       {
         <<CODE
             \$P0 = _md5sum ("$_")
             _md5_print (\$P0)
             print "\\n"
  CODE
  ;
       }
       (
        "0",
        "01",
        "012",
        "0123",
        "01234",
        "012345",
        "0123456",
        "01234567",
        "012345678",
        "0123456789",
        "01234567890",
        "012345678901",
        "0123456789012",
        "01234567890123",
        "012345678901234",
        "0123456789012345",
        "01234567890123456",
        "012345678901234567",
        "0123456789012345678",
        "01234567890123456789",
        "012345678901234567890",
        "0123456789012345678901",
        "01234567890123456789012",
        "012345678901234567890123",
        "0123456789012345678901234",
        "01234567890123456789012345",
        "012345678901234567890123456",
        "0123456789012345678901234567",
        "01234567890123456789012345678",
        "012345678901234567890123456789",
        "0123456789012345678901234567890",
        "01234567890123456789012345678901",
        "012345678901234567890123456789012",
        "0123456789012345678901234567890123",
        "01234567890123456789012345678901234",
        "012345678901234567890123456789012345",
        "0123456789012345678901234567890123456",
        "01234567890123456789012345678901234567",
        "012345678901234567890123456789012345678",
        "0123456789012345678901234567890123456789",
        "01234567890123456789012345678901234567890",
        "012345678901234567890123456789012345678901",
        "0123456789012345678901234567890123456789012",
        "01234567890123456789012345678901234567890123",
        "012345678901234567890123456789012345678901234",
        "0123456789012345678901234567890123456789012345",
        "01234567890123456789012345678901234567890123456",
        "012345678901234567890123456789012345678901234567",
        "0123456789012345678901234567890123456789012345678",
        "01234567890123456789012345678901234567890123456789",
        "012345678901234567890123456789012345678901234567890",
        "0123456789012345678901234567890123456789012345678901",
        "01234567890123456789012345678901234567890123456789012",
        "012345678901234567890123456789012345678901234567890123",
        "0123456789012345678901234567890123456789012345678901234",
        "01234567890123456789012345678901234567890123456789012345",
        "012345678901234567890123456789012345678901234567890123456",
        "0123456789012345678901234567890123456789012345678901234567",
        "01234567890123456789012345678901234567890123456789012345678",
        "012345678901234567890123456789012345678901234567890123456789",
        "0123456789012345678901234567890123456789012345678901234567890",
        "01234567890123456789012345678901234567890123456789012345678901",
        "012345678901234567890123456789012345678901234567890123456789012",
        "0123456789012345678901234567890123456789012345678901234567890123",
        "01234567890123456789012345678901234567890123456789012345678901234",
        "012345678901234567890123456789012345678901234567890123456789012345",
        "0123456789012345678901234567890123456789012345678901234567890123456",
        "01234567890123456789012345678901234567890123456789012345678901234567",
        "012345678901234567890123456789012345678901234567890123456789012345678",
        
"0123456789012345678901234567890123456789012345678901234567890123456789",
        
"01234567890123456789012345678901234567890123456789012345678901234567890",
        
"012345678901234567890123456789012345678901234567890123456789012345678901",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567",
        
"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678",
        
"01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
        
"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
  
  
        )) ;
  
  pir_output_is(<<CODE, <<'OUT', "String lengths");
  .sub _main
      load_bytecode "library/Digest/MD5.imc"
      $code
      end
  .end
  CODE
  cfcd208495d565ef66e7dff9f98764da
  96a3be3cf272e017046d1b2674a52bd3
  d2490f048dc3b77a457e3e450ab4eb38
  eb62f6b9306db575c2d596b1279627a4
  4100c4d44da9177247e44a5fc1546778
  d6a9a933c8aafc51e55ac0662b6e4d4a
  124bd1296bec0d9d93c7b52a71ad8d5b
  2e9ec317e197819358fbc43afca7d837
  22975d8a5ed1b91445f6c55ac121505b
  781e5e245d69b566979b86e28d23f2c7
  ebe596017db2f8c69136e5d6e594d365
  9a09ac0f4c8c2f92d77f2d77612b6f78
  28e23e897f070c849a86cd60b9a852c1
  ae248bb2a77e470cb92d8e69e5f5affc
  78f40ab0050544f9de011de7a4c6ecdb
  d927ad81199aa7dcadfdb4e47b6dc694
  6def23346f64e0163d9924f2f40c9cf2
  d02ebde979264c79e141559fc9f6b65c
  b61fd0bcc895bb16c784558934586d97
  be497c2168e374f414a351c49379c01a
  eaf9acee4b07a9986ce13edadd72ffcc
  8b50575826e6ab4102f1335396b29bba
  dbdf3116a6627638bff94877f31e56af
  607e25deb0f2d06cbbb4d774d60e9aeb
  845379ce1cb6ab954f40261250a7d9c8
  c548d9f9273d070ada6070611b609e29
  d0e16d114b9299f418e781feb7e189ca
  7ab3976c761a67b2a1e57bf9eade8576
  fecfbf31a749c7403612c47c3633ba6e
  4f7223ebadee9fb57b6796570d60638f
  274f173711cb1d36f5ce2d4d48ac2350
  298bf0197a05149e366b6bb61835a1c1
  cf09b5cb769d068e70d248ac7e013ac9
  c448e84be268303d169b20280f82bc8b
  541a6eada38facbba17bff5ed44512e5
  358ab3835dd5371cc890ebadba6c6d6d
  3887ce467d1e74ad307acb8896bffeea
  f8ea4cba02b3cb898dcb8cef543845b7
  8fbaa7868a809afb8a10f910dc6ce372
  9f0ae0380ed27dbf6b852843d2eece1f
  258b326512843f996b693fe0fc3ab34a
  486011c2adb42c5dba82bec5114dc1fc
  4870e0d70c0ef3f920286ccbd316a23d
  e8d950dec279b91a52d06283592ce27c
  604a4d755ea290e04ed2999243bf5b4a
  985170ea843a93803a560dc7f445e938
  a99cecea30006f01a7ca56b4845cfb7a
  a73df556df9e6ceca5d2d3903d639813
  fa7499e1c713703d7b28f99cd7f5c654
  baed005300234f3d1503c50a48ce8e6f
  8c3ef34e616209cb0efe0f6b735c110d
  240d6ec1fe28630a9cc9a4978e5524f1
  a3360e2d7e28ed4572c3dc16ef705372
  3dff83c8fadd26370d5b098409644457
  6e7a4fc92eb1c3f6e652425bcc8d44b5
  8af270b2847610e742b0791b53648c09
  c620bace4cde41bc45a14cfa62ee3487
  66f6bb54a54f967caa2607ad2990ecb4
  ad76b175d22a98a4e3bc2ad72affc53e
  1ced811af47ead374872fcca9d73dd71
  057a79e90fca0d805e0938d8e38a638b
  10f0b5ba92a04c7502dec778490a9acb
  c5e256437e758092dbfe06283e489019
  7f7bfd348709deeaace19e3f535f8c54
  beb9f48bc802ca5ca043bcc15e219a5a
  d6329b22b4b67da8120d0074eb28cb31
  061accc64d9dbd228685091cf76d6f58
  7ad76683ed7802615406f4efaa1b8d8b
  b5c71592955c35707a4ba4edf8dd66de
  109eb12c10c45d94ddac8eca7b818bed
  8ca2dc1109ec719046f23d92efe819f7
  4e4c090b615aa77e69eacc7b77b5cf95
  841dba25c1ecaffe412e2e748330a8ae
  deb3cb2636d15d6aeccc1951b9d5f183
  a6407577c4b42b2e738ad6d56ed1f486
  e441c22735877b6c3c9357ba1820d708
  778a111027ce535d272143817e6e9d8d
  bcb0b673b05701772b02d6b747622c62
  471814de0f707d1f04ba37a7d31aba36
  0faef1f4cb01d560d59016a2d5e91da6
  6e0c4c53a4178accb1c9b98556b8b945
  240b6fbc9d3be13b28e949fc5e94a92c
  004ef599b79db30564f653354fa2165a
  92d36974a72cdde56527eb7e26603075
  42b33f3421b374998baab3d0ce9915c7
  6cda32041571c398fad2b5979321949b
  dcf3495e733de25b7a0465159c48b098
  0c6b4c69e1380ecc74124be9a080a2bd
  321c5993da3dee64c550e87b81f9af73
  3b9739dbce23373276d22e2709e82f6e
  db52e041b6faca67496bae11d5177ce9
  6e9f209cf47edc69a21b6cc1f7f616f9
  95e99b94cdcec3b6f4a2820fb87cd9ed
  08eed5e9006f867fb5dedfc42b082df8
  7418f52788313c121eef974cd283e8a5
  b2b23cfd66f6bdd522c47315752d7731
  7c962704271a7a905cbec236de469626
  84e15104f912a6cb2768ebdde00e5b33
  dde798bd1d5336a07337aec45cb02576
  7a08b07e84641703e5f2c836aa59a170
  525cce3d8c3eaf36a756a91fcb996d59
  6fd9044eb098d000b86615ff9df50e11
  364603b2cf1662d139496c12f36f490a
  375e3afc44bf428c445bff4363f0dbe5
  477ac3a1c002d85755b40451c8db87d2
  3c6f3dfa17a3022cf18db24e42f54b96
  d2cfbebc441bea6a9c9c4a2faba865e2
  01fb84949f9192411682b39e2642b662
  2468a5c59cccb56bd51ed5ee766b2d2b
  09e32555adc12a6f2c8fed9a459935af
  6c27622d1d5365e4abfd02f2eccfd8f9
  OUT
  }
  
  
  

Reply via email to