add openssl/md5
Like `openssl/sha1`, the `openssl/md5` library falls back to the plain Racket `file/md5` implementation if OpenSSL is not available.
This commit is contained in:
parent
7e57274a64
commit
9e716b0422
|
@ -8,6 +8,9 @@
|
|||
|
||||
@defmodule[file/md5]
|
||||
|
||||
See @racketmodname[openssl/md5] for a faster implementation with a
|
||||
slightly different interface.
|
||||
|
||||
@defproc[(md5 [in (or/c input-port? bytes? string?)]
|
||||
[hex-encode? boolean? #t]) bytes?]{
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
@(require scribble/manual
|
||||
(for-label openssl
|
||||
racket
|
||||
openssl/sha1))
|
||||
openssl/sha1
|
||||
openssl/md5))
|
||||
|
||||
@title{OpenSSL: Secure Communication}
|
||||
|
||||
|
@ -649,3 +650,34 @@ until an end-of-file.}
|
|||
Converts the given byte string to a string representation, where each
|
||||
byte in @racket[bstr] is converted to its two-digit hexadecimal
|
||||
representation in the resulting string.}
|
||||
|
||||
@defproc[(hex-string->bytes [str string?]) bytes?]{
|
||||
|
||||
The inverse of @racket[bytes->hex-string].}
|
||||
|
||||
@; ----------------------------------------------------------------------
|
||||
|
||||
@section{MD5 Hashing}
|
||||
|
||||
@defmodule[openssl/md5]{The @racketmodname[openssl/md5] library
|
||||
provides a Racket wrapper for the OpenSSL library's MD5 hashing
|
||||
functions. If the OpenSSL library cannot be opened, this library logs
|
||||
a warning and falls back to the implementation in
|
||||
@racketmodname[file/md5].}
|
||||
|
||||
@history[#:added "6.0.0.3"]
|
||||
|
||||
@defproc[(md5 [in input-port?]) string?]{
|
||||
|
||||
Returns a 32-character string that represents the MD5 hash (in
|
||||
hexadecimal notation) of the content from @racket[in], consuming all
|
||||
of the input from @racket[in] until an end-of-file.
|
||||
|
||||
The @racket[md5] function composes @racket[bytes->hex-string] with
|
||||
@racket[md5-bytes].}
|
||||
|
||||
@defproc[(md5-bytes [in input-port?]) bytes?]{
|
||||
|
||||
Returns a 16-byte byte string that represents the MD5 hash of the
|
||||
content from @racket[in], consuming all of the input from @racket[in]
|
||||
until an end-of-file.}
|
||||
|
|
57
racket/collects/openssl/md5.rkt
Normal file
57
racket/collects/openssl/md5.rkt
Normal file
|
@ -0,0 +1,57 @@
|
|||
#lang racket/base
|
||||
(require ffi/unsafe
|
||||
racket/runtime-path
|
||||
(for-syntax racket/base)
|
||||
(prefix-in r: file/md5)
|
||||
"libcrypto.rkt")
|
||||
|
||||
(provide md5
|
||||
md5-bytes)
|
||||
|
||||
(define _SHA_CTX-pointer _pointer)
|
||||
|
||||
(define MD5_Init
|
||||
(and libcrypto
|
||||
(get-ffi-obj 'MD5_Init libcrypto (_fun _SHA_CTX-pointer -> _int) (lambda () #f))))
|
||||
(define MD5_Update
|
||||
(and libcrypto
|
||||
(get-ffi-obj 'MD5_Update libcrypto (_fun _SHA_CTX-pointer _pointer _long -> _int) (lambda () #f))))
|
||||
(define MD5_Final
|
||||
(and libcrypto
|
||||
(get-ffi-obj 'MD5_Final libcrypto (_fun _pointer _SHA_CTX-pointer -> _int) (lambda () #f))))
|
||||
|
||||
(define (md5-bytes in)
|
||||
(unless (input-port? in) (raise-argument-error 'md5-bytes "input-port?" in))
|
||||
(if MD5_Init
|
||||
(let ([ctx (malloc 256)]
|
||||
[tmp (make-bytes 4096)]
|
||||
[result (make-bytes 16)])
|
||||
(MD5_Init ctx)
|
||||
(let loop ()
|
||||
(let ([n (read-bytes-avail! tmp in)])
|
||||
(unless (eof-object? n)
|
||||
(MD5_Update ctx tmp n)
|
||||
(loop))))
|
||||
(MD5_Final result ctx)
|
||||
result)
|
||||
(r:md5 in #f)))
|
||||
|
||||
(define (md5 in)
|
||||
(unless (input-port? in) (raise-argument-error 'md5 "input-port?" in))
|
||||
(bytes->hex-string (md5-bytes in)))
|
||||
|
||||
;; copied from `file/sha1` --- should be in a separate module,
|
||||
;; instead
|
||||
(define (bytes->hex-string bstr)
|
||||
(let* ([len (bytes-length bstr)]
|
||||
[bstr2 (make-bytes (* len 2))]
|
||||
[digit
|
||||
(lambda (v)
|
||||
(if (v . < . 10)
|
||||
(+ v (char->integer #\0))
|
||||
(+ v (- (char->integer #\a) 10))))])
|
||||
(for ([i (in-range len)])
|
||||
(let ([c (bytes-ref bstr i)])
|
||||
(bytes-set! bstr2 (* 2 i) (digit (arithmetic-shift c -4)))
|
||||
(bytes-set! bstr2 (+ (* 2 i) 1) (digit (bitwise-and c #xF)))))
|
||||
(bytes->string/latin-1 bstr2)))
|
|
@ -23,6 +23,7 @@
|
|||
(get-ffi-obj 'SHA1_Final libcrypto (_fun _pointer _SHA_CTX-pointer -> _int) (lambda () #f))))
|
||||
|
||||
(define (sha1-bytes in)
|
||||
(unless (input-port? in) (raise-argument-error 'sha1-bytes "input-port?" in))
|
||||
(if SHA1_Init
|
||||
(let ([ctx (malloc 256)]
|
||||
[tmp (make-bytes 4096)]
|
||||
|
@ -38,4 +39,5 @@
|
|||
(r:sha1-bytes in)))
|
||||
|
||||
(define (sha1 in)
|
||||
(unless (input-port? in) (raise-argument-error 'sha1 "input-port?" in))
|
||||
(r:bytes->hex-string (sha1-bytes in)))
|
||||
|
|
Loading…
Reference in New Issue
Block a user