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.
60 lines
1.3 KiB
60 lines
1.3 KiB
// !build linux,amd64
|
|
|
|
package md5c
|
|
|
|
// /* Any 32-bit or wider unsigned integer data type will do */
|
|
// typedef unsigned int MD5_u32plus;
|
|
//
|
|
// typedef struct {
|
|
// MD5_u32plus lo, hi;
|
|
// MD5_u32plus a, b, c, d;
|
|
// unsigned char buffer[64];
|
|
// MD5_u32plus block[16];
|
|
// } MD5_CTX;
|
|
//
|
|
// void MD5_Init(MD5_CTX *ctx);
|
|
// void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
|
// void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
|
import "C"
|
|
import (
|
|
"io"
|
|
"unsafe"
|
|
)
|
|
|
|
func context() *C.MD5_CTX {
|
|
var ctx C.MD5_CTX
|
|
C.MD5_Init(&ctx)
|
|
return &ctx
|
|
}
|
|
|
|
func write(buffer []byte, ctx *C.MD5_CTX) {
|
|
size := len(buffer)
|
|
data := unsafe.Pointer(&buffer[0])
|
|
C.MD5_Update(ctx, data, C.ulong(size))
|
|
}
|
|
|
|
func Sum(reader io.Reader) ([]byte, error) {
|
|
ctx := context()
|
|
var err error
|
|
var length int
|
|
for err == nil {
|
|
byteBuffer := make([]byte, 1024*1024)
|
|
length, err = reader.Read(byteBuffer)
|
|
// break here since byteBuffer will go out of range
|
|
// when invoking subsequent write() call
|
|
if length == 0 {
|
|
break
|
|
}
|
|
byteBuffer = byteBuffer[0:length]
|
|
write(byteBuffer, ctx)
|
|
}
|
|
|
|
if err != io.EOF {
|
|
return nil, err
|
|
}
|
|
|
|
outputBuffer := make([]byte, 16)
|
|
coutputbuff := (*C.uchar)(unsafe.Pointer(&outputBuffer[0]))
|
|
C.MD5_Final(coutputbuff, ctx)
|
|
return outputBuffer, nil
|
|
}
|
|
|