Add new primitives to simplify writing code to perform MD5 checksum on
authorChris Hanson <org/chris-hanson/cph>
Tue, 17 Jun 1997 04:58:06 +0000 (04:58 +0000)
committerChris Hanson <org/chris-hanson/cph>
Tue, 17 Jun 1997 04:58:06 +0000 (04:58 +0000)
arbitrary-length streams.

v7/src/microcode/prmd5.c

index f5c9148c388d70575a332fe4672ab725c2de83d7..59d9186a28d0063fc61296882117aac7ff37e07a 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: prmd5.c,v 1.2 1997/06/09 21:17:11 cph Exp $
+$Id: prmd5.c,v 1.3 1997/06/17 04:58:06 cph Exp $
 
 Copyright (c) 1997 Massachusetts Institute of Technology
 
@@ -37,7 +37,7 @@ MIT in each case. */
 #include "scheme.h"
 #include "prims.h"
 #include <md5.h>
-
+\f
 DEFINE_PRIMITIVE ("MD5", Prim_md5, 1, 1,
   "(STRING)\n\
 Generate an MD5 digest of string.\n\
@@ -60,3 +60,62 @@ The digest is returned as a 16-byte string.")
     PRIMITIVE_RETURN (result);
   }
 }
+
+DEFINE_PRIMITIVE ("MD5-INIT", Prim_md5_init, 0, 0,
+  "()\n\
+Create and return an MD5 digest context.")
+{
+  PRIMITIVE_HEADER (0);
+  {
+    SCHEME_OBJECT context = (allocate_string (sizeof (MD5_CTX)));
+    MD5Init ((MD5_CTX *) (STRING_LOC (context, 0)));
+    PRIMITIVE_RETURN (context);
+  }
+}
+
+static MD5_CTX *
+DEFUN (md5_context_arg, (arg), int arg)
+{
+  CHECK_ARG (arg, STRING_P);
+  if ((STRING_LENGTH (ARG_REF (arg))) != (sizeof (MD5_CTX)))
+    error_bad_range_arg (arg);
+  return ((MD5_CTX *) (STRING_LOC ((ARG_REF (arg)), 0)));
+}
+
+DEFINE_PRIMITIVE ("MD5-UPDATE", Prim_md5_update, 4, 4,
+  "(CONTEXT STRING START END)\n\
+Update CONTEXT with the contents of the substring (STRING,START,END).")
+{
+  PRIMITIVE_HEADER (4);
+  CHECK_ARG (2, STRING_P);
+  {
+    SCHEME_OBJECT string = (ARG_REF (2));
+    unsigned long l = (STRING_LENGTH (string));
+    unsigned long start = (arg_ulong_index_integer (3, l));
+    unsigned long end = (arg_integer_in_range (4, start, (l + 1)));
+    MD5Update ((md5_context_arg (1)),
+              (STRING_LOC (string, start)),
+              (end - start));
+    PRIMITIVE_RETURN (UNSPECIFIC);
+  }
+}
+
+DEFINE_PRIMITIVE ("MD5-FINAL", Prim_md5_final, 1, 1,
+  "(CONTEXT)\n\
+Finalize CONTEXT and return the digest as a 16-byte string.")
+{
+  PRIMITIVE_HEADER (1);
+  {
+    MD5_CTX * context = (md5_context_arg (1));
+    MD5Final (context);
+    {
+      SCHEME_OBJECT result = (allocate_string (16));
+      unsigned char * scan_result = (STRING_LOC (result, 0));
+      unsigned char * scan_digest = (context -> digest);
+      unsigned char * end_digest = (scan_digest + 16);
+      while (scan_digest < end_digest)
+       (*scan_result++) = (*scan_digest++);
+      PRIMITIVE_RETURN (result);
+    }
+  }
+}