home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / xp / xp_md5.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  3.0 KB  |  94 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19.  
  20. #include "sechash.h"
  21. #include "xp_md5.h"
  22. #include "xp_mem.h"
  23. #include "xpassert.h"
  24.  
  25. /*
  26.  * XP_Md5Binary(data, digest)
  27.  *    calculates the MD5 signature for 'data' which is NULL-terminated,
  28.  *    and places the 16-byte binary signature into 'digest' which must
  29.  *    be allocated by the caller.
  30.  *
  31.  */
  32. PUBLIC void XP_Md5Binary(char *data, int len, unsigned char digest[16])
  33. {
  34.     MD5_HashBuf(digest, (unsigned char *)data, len);
  35. }
  36.  
  37.  
  38. static char xp_pr[] = "0123456789abcdefghijklmnopqrstuv";
  39.  
  40. /*
  41.  * XP_Md5PCPrintable(data, len)
  42.  *      Makes a call to XP_Md5Binary, which turns a buffer of length 'len'
  43.  *      into a 16 byte digest.  This routine then turns the 16 binary bytes
  44.  *      into 24 readable bytes.  It is the responsibility of the caller
  45.  *      to free this string.
  46.  *
  47.  *    This maps only five bits to each char to make it work on the
  48.  *    braindead, case-insensitive-filesystem PC, aaaarrgh.
  49.  *
  50.  *    So for each 5 bytes it takes, it gives 8 printable bytes,
  51.  *    with bits taken from original data as follows:
  52.  *
  53.  *    [byte][bit]..[byte][bit]    byte=0..4, bit=1..8
  54.  *
  55.  *    [0][1]..[0][5]
  56.  *    [0][6]..[1][2]
  57.  *    [1][3]..[1][7]
  58.  *    [1][8]..[2][4]
  59.  *    [2][5]..[3][1]
  60.  *    [3][2]..[3][6]
  61.  *    [3][7]..[4][3]
  62.  *    [4][4]..[4][8]
  63.  *
  64.  */
  65. PUBLIC char *XP_Md5PCPrintable(char *data, int len)
  66. {
  67.     unsigned char digest[16];
  68.     char* buf = (char*) XP_ALLOC(25); /* 16 bytes -> 24 printable bytes */
  69.     register int i, j;
  70.  
  71.     if ( buf == NULL ) return NULL;
  72.  
  73.     XP_Md5Binary(data, len, digest);
  74.  
  75.     /* Aaargh, somebody come up with a more mathematical formula to do this
  76.        without hardcoded numbers.
  77.      */
  78.     for (i=j=0; i<15; i+=5, j+=8)
  79.       {
  80.       buf[j  ] = xp_pr[                             (digest[i  ] >> 3)];
  81.       buf[j+1] = xp_pr[((digest[i  ] &   7) << 2) | (digest[i+1] >> 6)];
  82.       buf[j+2] = xp_pr[((digest[i+1] &  63) >> 1)                     ];
  83.       buf[j+3] = xp_pr[((digest[i+1] &   1) << 4) | (digest[i+2] >> 4)];
  84.       buf[j+4] = xp_pr[((digest[i+2] &  15) << 1) | (digest[i+3] >> 7)];
  85.       buf[j+5] = xp_pr[((digest[i+3] & 127) >> 2)                     ];
  86.       buf[j+6] = xp_pr[((digest[i+3] &   3) << 3) | (digest[i+4] >> 5)];
  87.       buf[j+7] = xp_pr[((digest[i+4] &  31)     )                     ];
  88.       }
  89.  
  90.     buf[24] = '\0';
  91.  
  92.     return buf;
  93. }
  94.