summaryrefslogtreecommitdiff
path: root/ext/md5/md5init.c
blob: 9827b784cfa7e2085f9fbb35c478a58bc106908e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/************************************************

  md5init.c -

  $Author$
  created at: Fri Aug  2 09:24:12 JST 1996

  Copyright (C) 1995-2001 Yukihiro Matsumoto

************************************************/
/* This module provides an interface to the RSA Data Security,
   Inc. MD5 Message-Digest Algorithm, described in RFC 1321. */

#include "ruby.h"
#include "md5.h"

static VALUE cMD5;

static VALUE
md5i_update(obj, str)
    VALUE obj, str;
{
    md5_state_t *md5;
    char *p;
    int len;

    p = rb_str2cstr(str, &len);
    Data_Get_Struct(obj, md5_state_t, md5);
    md5_append(md5, p, len);

    return obj;
}

static VALUE
md5i_digest(obj)
    VALUE obj;
{
    md5_state_t *md5, ctx;
    md5_byte_t digest[16];

    Data_Get_Struct(obj, md5_state_t, md5);
    ctx = *md5;
    md5_finish(&ctx, digest);

    return rb_str_new(digest, 16);
}

static VALUE
md5i_hexdigest(obj)
    VALUE obj;
{
    md5_state_t *md5, ctx;
    md5_byte_t digest[16];
    char buf[33];
    int i;

    Data_Get_Struct(obj, md5_state_t, md5);
    ctx = *md5;
    md5_finish(&ctx, digest);

    for (i=0; i<16; i++) {
	sprintf(buf+i*2, "%02x", digest[i]);
    }
    return rb_str_new(buf, 32);
}

static VALUE
md5i_clone(obj)
    VALUE obj;
{
    md5_state_t *md5, *md5_new;

    Data_Get_Struct(obj, md5_state_t, md5);
    obj = Data_Make_Struct(CLASS_OF(obj), md5_state_t, 0, free, md5_new);
    *md5_new = *md5;

    return obj;
}

static VALUE
md5i_new(argc, argv, class)
    int argc;
    VALUE* argv;
    VALUE class;
{
    VALUE obj;
    md5_state_t *md5;

    obj = Data_Make_Struct(class, md5_state_t, 0, free, md5);
    md5_init(md5);
    if (argc == 1) {
	md5i_update(obj, argv[0]);
    }

    return obj;
}

void
Init_md5()
{
    cMD5 = rb_define_class("MD5", rb_cObject);

    rb_define_singleton_method(cMD5, "new", md5i_new, -1);
    rb_define_singleton_method(cMD5, "md5", md5i_new, -1);

    rb_define_method(cMD5, "update", md5i_update, 1);
    rb_define_method(cMD5, "digest", md5i_digest, 0);
    rb_define_method(cMD5, "hexdigest", md5i_hexdigest, 0);
    rb_define_method(cMD5, "clone",  md5i_clone, 0);
}