Ruby
2.1.3p242(2014-09-19revision47630)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
digest
digest.c
Go to the documentation of this file.
1
/************************************************
2
3
digest.c -
4
5
$Author: nagachika $
6
created at: Fri May 25 08:57:27 JST 2001
7
8
Copyright (C) 1995-2001 Yukihiro Matsumoto
9
Copyright (C) 2001-2006 Akinori MUSHA
10
11
$RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $
12
$Id: digest.c 46809 2014-07-13 14:24:26Z nagachika $
13
14
************************************************/
15
16
#include "
digest.h
"
17
18
static
VALUE
rb_mDigest
;
19
static
VALUE
rb_mDigest_Instance
;
20
static
VALUE
rb_cDigest_Class
;
21
static
VALUE
rb_cDigest_Base
;
22
23
static
ID
id_reset
,
id_update
,
id_finish
,
id_digest
,
id_hexdigest
,
id_digest_length
;
24
static
ID
id_metadata
;
25
26
RUBY_EXTERN
void
Init_digest_base
(
void
);
27
28
/*
29
* Document-module: Digest
30
*
31
* This module provides a framework for message digest libraries.
32
*
33
* You may want to look at OpenSSL::Digest as it supports more algorithms.
34
*
35
* A cryptographic hash function is a procedure that takes data and returns a
36
* fixed bit string: the hash value, also known as _digest_. Hash functions
37
* are also called one-way functions, it is easy to compute a digest from
38
* a message, but it is infeasible to generate a message from a digest.
39
*
40
* == Examples
41
*
42
* require 'digest'
43
*
44
* # Compute a complete digest
45
* Digest::SHA256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
46
*
47
* sha256 = Digest::SHA256.new
48
* sha256.digest 'message' #=> "\xABS\n\x13\xE4Y..."
49
*
50
* # Other encoding formats
51
* Digest::SHA256.hexdigest 'message' #=> "ab530a13e459..."
52
* Digest::SHA256.base64digest 'message' #=> "q1MKE+RZFJgr..."
53
*
54
* # Compute digest by chunks
55
* md5 = Digest::MD5.new
56
* md5.update 'message1'
57
* md5 << 'message2' # << is an alias for update
58
*
59
* md5.hexdigest #=> "94af09c09bb9..."
60
*
61
* # Compute digest for a file
62
* sha256 = Digest::SHA256.file 'testfile'
63
* sha256.hexdigest
64
*
65
* Additionally digests can be encoded in "bubble babble" format as a sequence
66
* of consonants and vowels which is more recognizable and comparable than a
67
* hexadecimal digest.
68
*
69
* require 'digest/bubblebabble'
70
*
71
* Digest::SHA256.bubblebabble 'message' #=> "xopoh-fedac-fenyh-..."
72
*
73
* See the bubble babble specification at
74
* http://web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt.
75
*
76
* == Digest algorithms
77
*
78
* Different digest algorithms (or hash functions) are available:
79
*
80
* HMAC::
81
* See FIPS PUB 198 The Keyed-Hash Message Authentication Code (HMAC).
82
* RIPEMD-160::
83
* As Digest::RMD160.
84
* See http://homes.esat.kuleuven.be/~bosselae/ripemd160.html.
85
* SHA1::
86
* See FIPS 180 Secure Hash Standard.
87
* SHA2 family::
88
* See FIPS 180 Secure Hash Standard which defines the following algorithms:
89
* * SHA512
90
* * SHA384
91
* * SHA256
92
*
93
* The latest versions of the FIPS publications can be found here:
94
* http://csrc.nist.gov/publications/PubsFIPS.html.
95
*/
96
97
static
VALUE
98
hexencode_str_new
(
VALUE
str_digest)
99
{
100
char
*digest;
101
size_t
digest_len;
102
size_t
i;
103
VALUE
str;
104
char
*p;
105
static
const
char
hex[] = {
106
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
107
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
108
};
109
110
StringValue
(str_digest);
111
digest =
RSTRING_PTR
(str_digest);
112
digest_len =
RSTRING_LEN
(str_digest);
113
114
if
(
LONG_MAX
/ 2 < digest_len) {
115
rb_raise
(
rb_eRuntimeError
,
"digest string too long"
);
116
}
117
118
str =
rb_usascii_str_new
(0, digest_len * 2);
119
120
for
(i = 0, p =
RSTRING_PTR
(str); i < digest_len; i++) {
121
unsigned
char
byte = digest[i];
122
123
p[i + i] = hex[byte >> 4];
124
p[i + i + 1] = hex[byte & 0x0f];
125
}
126
127
return
str;
128
}
129
130
/*
131
* call-seq:
132
* Digest.hexencode(string) -> hexencoded_string
133
*
134
* Generates a hex-encoded version of a given _string_.
135
*/
136
static
VALUE
137
rb_digest_s_hexencode
(
VALUE
klass,
VALUE
str)
138
{
139
return
hexencode_str_new
(str);
140
}
141
142
NORETURN
(
static
void
rb_digest_instance_method_unimpl
(
VALUE
self
,
const
char
*method));
143
144
/*
145
* Document-module: Digest::Instance
146
*
147
* This module provides instance methods for a digest implementation
148
* object to calculate message digest values.
149
*/
150
151
static
void
152
rb_digest_instance_method_unimpl
(
VALUE
self
,
const
char
*method)
153
{
154
rb_raise
(
rb_eRuntimeError
,
"%s does not implement %s()"
,
155
rb_obj_classname
(
self
), method);
156
}
157
158
/*
159
* call-seq:
160
* digest_obj.update(string) -> digest_obj
161
* digest_obj << string -> digest_obj
162
*
163
* Updates the digest using a given _string_ and returns self.
164
*
165
* The update() method and the left-shift operator are overridden by
166
* each implementation subclass. (One should be an alias for the
167
* other)
168
*/
169
static
VALUE
170
rb_digest_instance_update
(
VALUE
self
,
VALUE
str)
171
{
172
rb_digest_instance_method_unimpl
(
self
,
"update"
);
173
174
UNREACHABLE
;
175
}
176
177
/*
178
* call-seq:
179
* digest_obj.instance_eval { finish } -> digest_obj
180
*
181
* Finishes the digest and returns the resulting hash value.
182
*
183
* This method is overridden by each implementation subclass and often
184
* made private, because some of those subclasses may leave internal
185
* data uninitialized. Do not call this method from outside. Use
186
* #digest!() instead, which ensures that internal data be reset for
187
* security reasons.
188
*/
189
static
VALUE
190
rb_digest_instance_finish
(
VALUE
self
)
191
{
192
rb_digest_instance_method_unimpl
(
self
,
"finish"
);
193
194
UNREACHABLE
;
195
}
196
197
/*
198
* call-seq:
199
* digest_obj.reset -> digest_obj
200
*
201
* Resets the digest to the initial state and returns self.
202
*
203
* This method is overridden by each implementation subclass.
204
*/
205
static
VALUE
206
rb_digest_instance_reset
(
VALUE
self
)
207
{
208
rb_digest_instance_method_unimpl
(
self
,
"reset"
);
209
210
UNREACHABLE
;
211
}
212
213
/*
214
* call-seq:
215
* digest_obj.new -> another_digest_obj
216
*
217
* Returns a new, initialized copy of the digest object. Equivalent
218
* to digest_obj.clone().reset().
219
*/
220
static
VALUE
221
rb_digest_instance_new
(
VALUE
self
)
222
{
223
VALUE
clone =
rb_obj_clone
(
self
);
224
rb_funcall
(clone,
id_reset
, 0);
225
return
clone;
226
}
227
228
/*
229
* call-seq:
230
* digest_obj.digest -> string
231
* digest_obj.digest(string) -> string
232
*
233
* If none is given, returns the resulting hash value of the digest,
234
* keeping the digest's state.
235
*
236
* If a _string_ is given, returns the hash value for the given
237
* _string_, resetting the digest to the initial state before and
238
* after the process.
239
*/
240
static
VALUE
241
rb_digest_instance_digest
(
int
argc
,
VALUE
*
argv
,
VALUE
self
)
242
{
243
VALUE
str, value;
244
245
if
(
rb_scan_args
(argc, argv,
"01"
, &str) > 0) {
246
rb_funcall
(
self
,
id_reset
, 0);
247
rb_funcall
(
self
,
id_update
, 1, str);
248
value =
rb_funcall
(
self
,
id_finish
, 0);
249
rb_funcall
(
self
,
id_reset
, 0);
250
}
else
{
251
value =
rb_funcall
(
rb_obj_clone
(
self
),
id_finish
, 0);
252
}
253
254
return
value;
255
}
256
257
/*
258
* call-seq:
259
* digest_obj.digest! -> string
260
*
261
* Returns the resulting hash value and resets the digest to the
262
* initial state.
263
*/
264
static
VALUE
265
rb_digest_instance_digest_bang
(
VALUE
self
)
266
{
267
VALUE
value =
rb_funcall
(
self
,
id_finish
, 0);
268
rb_funcall
(
self
,
id_reset
, 0);
269
270
return
value;
271
}
272
273
/*
274
* call-seq:
275
* digest_obj.hexdigest -> string
276
* digest_obj.hexdigest(string) -> string
277
*
278
* If none is given, returns the resulting hash value of the digest in
279
* a hex-encoded form, keeping the digest's state.
280
*
281
* If a _string_ is given, returns the hash value for the given
282
* _string_ in a hex-encoded form, resetting the digest to the initial
283
* state before and after the process.
284
*/
285
static
VALUE
286
rb_digest_instance_hexdigest
(
int
argc
,
VALUE
*
argv
,
VALUE
self
)
287
{
288
VALUE
str, value;
289
290
if
(
rb_scan_args
(argc, argv,
"01"
, &str) > 0) {
291
rb_funcall
(
self
,
id_reset
, 0);
292
rb_funcall
(
self
,
id_update
, 1, str);
293
value =
rb_funcall
(
self
,
id_finish
, 0);
294
rb_funcall
(
self
,
id_reset
, 0);
295
}
else
{
296
value =
rb_funcall
(
rb_obj_clone
(
self
),
id_finish
, 0);
297
}
298
299
return
hexencode_str_new
(value);
300
}
301
302
/*
303
* call-seq:
304
* digest_obj.hexdigest! -> string
305
*
306
* Returns the resulting hash value in a hex-encoded form and resets
307
* the digest to the initial state.
308
*/
309
static
VALUE
310
rb_digest_instance_hexdigest_bang
(
VALUE
self
)
311
{
312
VALUE
value =
rb_funcall
(
self
,
id_finish
, 0);
313
rb_funcall
(
self
,
id_reset
, 0);
314
315
return
hexencode_str_new
(value);
316
}
317
318
/*
319
* call-seq:
320
* digest_obj.to_s -> string
321
*
322
* Returns digest_obj.hexdigest().
323
*/
324
static
VALUE
325
rb_digest_instance_to_s
(
VALUE
self
)
326
{
327
return
rb_funcall
(
self
,
id_hexdigest
, 0);
328
}
329
330
/*
331
* call-seq:
332
* digest_obj.inspect -> string
333
*
334
* Creates a printable version of the digest object.
335
*/
336
static
VALUE
337
rb_digest_instance_inspect
(
VALUE
self
)
338
{
339
VALUE
str;
340
size_t
digest_len = 32;
/* about this size at least */
341
const
char
*cname;
342
343
cname =
rb_obj_classname
(
self
);
344
345
/* #<Digest::ClassName: xxxxx...xxxx> */
346
str =
rb_str_buf_new
(2 +
strlen
(cname) + 2 + digest_len * 2 + 1);
347
rb_str_buf_cat2
(str,
"#<"
);
348
rb_str_buf_cat2
(str, cname);
349
rb_str_buf_cat2
(str,
": "
);
350
rb_str_buf_append
(str,
rb_digest_instance_hexdigest
(0, 0,
self
));
351
rb_str_buf_cat2
(str,
">"
);
352
return
str;
353
}
354
355
/*
356
* call-seq:
357
* digest_obj == another_digest_obj -> boolean
358
* digest_obj == string -> boolean
359
*
360
* If a string is given, checks whether it is equal to the hex-encoded
361
* hash value of the digest object. If another digest instance is
362
* given, checks whether they have the same hash value. Otherwise
363
* returns false.
364
*/
365
static
VALUE
366
rb_digest_instance_equal
(
VALUE
self
,
VALUE
other)
367
{
368
VALUE
str1, str2;
369
370
if
(
rb_obj_is_kind_of
(other,
rb_mDigest_Instance
) ==
Qtrue
) {
371
str1 =
rb_digest_instance_digest
(0, 0,
self
);
372
str2 =
rb_digest_instance_digest
(0, 0, other);
373
}
else
{
374
str1 =
rb_digest_instance_to_s
(
self
);
375
str2 =
rb_check_string_type
(other);
376
if
(
NIL_P
(str2))
return
Qfalse
;
377
}
378
379
/* never blindly assume that subclass methods return strings */
380
StringValue
(str1);
381
StringValue
(str2);
382
383
if
(
RSTRING_LEN
(str1) ==
RSTRING_LEN
(str2) &&
384
rb_str_cmp
(str1, str2) == 0) {
385
return
Qtrue
;
386
}
387
return
Qfalse
;
388
}
389
390
/*
391
* call-seq:
392
* digest_obj.digest_length -> integer
393
*
394
* Returns the length of the hash value of the digest.
395
*
396
* This method should be overridden by each implementation subclass.
397
* If not, digest_obj.digest().length() is returned.
398
*/
399
static
VALUE
400
rb_digest_instance_digest_length
(
VALUE
self
)
401
{
402
/* subclasses really should redefine this method */
403
VALUE
digest =
rb_digest_instance_digest
(0, 0,
self
);
404
405
/* never blindly assume that #digest() returns a string */
406
StringValue
(digest);
407
return
INT2NUM
(
RSTRING_LEN
(digest));
408
}
409
410
/*
411
* call-seq:
412
* digest_obj.length -> integer
413
* digest_obj.size -> integer
414
*
415
* Returns digest_obj.digest_length().
416
*/
417
static
VALUE
418
rb_digest_instance_length
(
VALUE
self
)
419
{
420
return
rb_funcall
(
self
,
id_digest_length
, 0);
421
}
422
423
/*
424
* call-seq:
425
* digest_obj.block_length -> integer
426
*
427
* Returns the block length of the digest.
428
*
429
* This method is overridden by each implementation subclass.
430
*/
431
static
VALUE
432
rb_digest_instance_block_length
(
VALUE
self
)
433
{
434
rb_digest_instance_method_unimpl
(
self
,
"block_length"
);
435
436
UNREACHABLE
;
437
}
438
439
/*
440
* Document-class: Digest::Class
441
*
442
* This module stands as a base class for digest implementation
443
* classes.
444
*/
445
446
/*
447
* call-seq:
448
* Digest::Class.digest(string, *parameters) -> hash_string
449
*
450
* Returns the hash value of a given _string_. This is equivalent to
451
* Digest::Class.new(*parameters).digest(string), where extra
452
* _parameters_, if any, are passed through to the constructor and the
453
* _string_ is passed to #digest().
454
*/
455
static
VALUE
456
rb_digest_class_s_digest
(
int
argc
,
VALUE
*
argv
,
VALUE
klass)
457
{
458
VALUE
str;
459
volatile
VALUE
obj;
460
461
if
(argc < 1) {
462
rb_raise
(
rb_eArgError
,
"no data given"
);
463
}
464
465
str = *argv++;
466
argc--;
467
468
StringValue
(str);
469
470
obj =
rb_obj_alloc
(klass);
471
rb_obj_call_init
(obj, argc, argv);
472
473
return
rb_funcall
(obj,
id_digest
, 1, str);
474
}
475
476
/*
477
* call-seq:
478
* Digest::Class.hexdigest(string[, ...]) -> hash_string
479
*
480
* Returns the hex-encoded hash value of a given _string_. This is
481
* almost equivalent to
482
* Digest.hexencode(Digest::Class.new(*parameters).digest(string)).
483
*/
484
static
VALUE
485
rb_digest_class_s_hexdigest
(
int
argc
,
VALUE
*
argv
,
VALUE
klass)
486
{
487
return
hexencode_str_new
(
rb_funcall2
(klass,
id_digest
, argc, argv));
488
}
489
490
/* :nodoc: */
491
static
VALUE
492
rb_digest_class_init
(
VALUE
self
)
493
{
494
return
self
;
495
}
496
497
/*
498
* Document-class: Digest::Base
499
*
500
* This abstract class provides a common interface to message digest
501
* implementation classes written in C.
502
*/
503
504
static
rb_digest_metadata_t
*
505
get_digest_base_metadata
(
VALUE
klass)
506
{
507
VALUE
p;
508
VALUE
obj;
509
rb_digest_metadata_t
*algo;
510
511
for
(p = klass; !
NIL_P
(p); p =
rb_class_superclass
(p)) {
512
if
(
rb_ivar_defined
(p,
id_metadata
)) {
513
obj =
rb_ivar_get
(p,
id_metadata
);
514
break
;
515
}
516
}
517
518
if
(
NIL_P
(p))
519
rb_raise
(
rb_eRuntimeError
,
"Digest::Base cannot be directly inherited in Ruby"
);
520
521
Data_Get_Struct
(obj,
rb_digest_metadata_t
, algo);
522
523
switch
(algo->
api_version
) {
524
case
2:
525
break
;
526
527
/*
528
* put conversion here if possible when API is updated
529
*/
530
531
default
:
532
rb_raise
(
rb_eRuntimeError
,
"Incompatible digest API version"
);
533
}
534
535
return
algo;
536
}
537
538
static
VALUE
539
rb_digest_base_alloc
(
VALUE
klass)
540
{
541
rb_digest_metadata_t
*algo;
542
VALUE
obj;
543
void
*pctx;
544
545
if
(klass ==
rb_cDigest_Base
) {
546
rb_raise
(
rb_eNotImpError
,
"Digest::Base is an abstract class"
);
547
}
548
549
algo =
get_digest_base_metadata
(klass);
550
551
pctx =
xmalloc
(algo->
ctx_size
);
552
algo->
init_func
(pctx);
553
554
obj =
Data_Wrap_Struct
(klass, 0,
xfree
, pctx);
555
556
return
obj;
557
}
558
559
/* :nodoc: */
560
static
VALUE
561
rb_digest_base_copy
(
VALUE
copy,
VALUE
obj)
562
{
563
rb_digest_metadata_t
*algo;
564
void
*pctx1, *pctx2;
565
566
if
(copy == obj)
return
copy;
567
568
rb_check_frozen
(copy);
569
570
algo =
get_digest_base_metadata
(
rb_obj_class
(copy));
571
572
Data_Get_Struct
(obj,
void
, pctx1);
573
Data_Get_Struct
(copy,
void
, pctx2);
574
memcpy(pctx2, pctx1, algo->
ctx_size
);
575
576
return
copy;
577
}
578
579
/* :nodoc: */
580
static
VALUE
581
rb_digest_base_reset
(
VALUE
self
)
582
{
583
rb_digest_metadata_t
*algo;
584
void
*pctx;
585
586
algo =
get_digest_base_metadata
(
rb_obj_class
(
self
));
587
588
Data_Get_Struct
(
self
,
void
, pctx);
589
590
algo->
init_func
(pctx);
591
592
return
self
;
593
}
594
595
/* :nodoc: */
596
static
VALUE
597
rb_digest_base_update
(
VALUE
self
,
VALUE
str)
598
{
599
rb_digest_metadata_t
*algo;
600
void
*pctx;
601
602
algo =
get_digest_base_metadata
(
rb_obj_class
(
self
));
603
604
Data_Get_Struct
(
self
,
void
, pctx);
605
606
StringValue
(str);
607
algo->
update_func
(pctx, (
unsigned
char
*)
RSTRING_PTR
(str),
RSTRING_LEN
(str));
608
609
return
self
;
610
}
611
612
/* :nodoc: */
613
static
VALUE
614
rb_digest_base_finish
(
VALUE
self
)
615
{
616
rb_digest_metadata_t
*algo;
617
void
*pctx;
618
VALUE
str;
619
620
algo =
get_digest_base_metadata
(
rb_obj_class
(
self
));
621
622
Data_Get_Struct
(
self
,
void
, pctx);
623
624
str =
rb_str_new
(0, algo->
digest_len
);
625
algo->
finish_func
(pctx, (
unsigned
char
*)
RSTRING_PTR
(str));
626
627
/* avoid potential coredump caused by use of a finished context */
628
algo->
init_func
(pctx);
629
630
return
str;
631
}
632
633
/* :nodoc: */
634
static
VALUE
635
rb_digest_base_digest_length
(
VALUE
self
)
636
{
637
rb_digest_metadata_t
*algo;
638
639
algo =
get_digest_base_metadata
(
rb_obj_class
(
self
));
640
641
return
INT2NUM
(algo->
digest_len
);
642
}
643
644
/* :nodoc: */
645
static
VALUE
646
rb_digest_base_block_length
(
VALUE
self
)
647
{
648
rb_digest_metadata_t
*algo;
649
650
algo =
get_digest_base_metadata
(
rb_obj_class
(
self
));
651
652
return
INT2NUM
(algo->
block_len
);
653
}
654
655
void
656
Init_digest
(
void
)
657
{
658
id_reset
=
rb_intern
(
"reset"
);
659
id_update
=
rb_intern
(
"update"
);
660
id_finish
=
rb_intern
(
"finish"
);
661
id_digest
=
rb_intern
(
"digest"
);
662
id_hexdigest
=
rb_intern
(
"hexdigest"
);
663
id_digest_length
=
rb_intern
(
"digest_length"
);
664
665
/*
666
* module Digest
667
*/
668
rb_mDigest
=
rb_define_module
(
"Digest"
);
669
670
/* module functions */
671
rb_define_module_function
(
rb_mDigest
,
"hexencode"
,
rb_digest_s_hexencode
, 1);
672
673
/*
674
* module Digest::Instance
675
*/
676
rb_mDigest_Instance
=
rb_define_module_under
(
rb_mDigest
,
"Instance"
);
677
678
/* instance methods that should be overridden */
679
rb_define_method
(
rb_mDigest_Instance
,
"update"
,
rb_digest_instance_update
, 1);
680
rb_define_method
(
rb_mDigest_Instance
,
"<<"
,
rb_digest_instance_update
, 1);
681
rb_define_private_method
(
rb_mDigest_Instance
,
"finish"
,
rb_digest_instance_finish
, 0);
682
rb_define_method
(
rb_mDigest_Instance
,
"reset"
,
rb_digest_instance_reset
, 0);
683
rb_define_method
(
rb_mDigest_Instance
,
"digest_length"
,
rb_digest_instance_digest_length
, 0);
684
rb_define_method
(
rb_mDigest_Instance
,
"block_length"
,
rb_digest_instance_block_length
, 0);
685
686
/* instance methods that may be overridden */
687
rb_define_method
(
rb_mDigest_Instance
,
"=="
,
rb_digest_instance_equal
, 1);
688
rb_define_method
(
rb_mDigest_Instance
,
"inspect"
,
rb_digest_instance_inspect
, 0);
689
690
/* instance methods that need not usually be overridden */
691
rb_define_method
(
rb_mDigest_Instance
,
"new"
,
rb_digest_instance_new
, 0);
692
rb_define_method
(
rb_mDigest_Instance
,
"digest"
,
rb_digest_instance_digest
, -1);
693
rb_define_method
(
rb_mDigest_Instance
,
"digest!"
,
rb_digest_instance_digest_bang
, 0);
694
rb_define_method
(
rb_mDigest_Instance
,
"hexdigest"
,
rb_digest_instance_hexdigest
, -1);
695
rb_define_method
(
rb_mDigest_Instance
,
"hexdigest!"
,
rb_digest_instance_hexdigest_bang
, 0);
696
rb_define_method
(
rb_mDigest_Instance
,
"to_s"
,
rb_digest_instance_to_s
, 0);
697
rb_define_method
(
rb_mDigest_Instance
,
"length"
,
rb_digest_instance_length
, 0);
698
rb_define_method
(
rb_mDigest_Instance
,
"size"
,
rb_digest_instance_length
, 0);
699
700
/*
701
* class Digest::Class
702
*/
703
rb_cDigest_Class
=
rb_define_class_under
(
rb_mDigest
,
"Class"
,
rb_cObject
);
704
rb_define_method
(
rb_cDigest_Class
,
"initialize"
,
rb_digest_class_init
, 0);
705
rb_include_module
(
rb_cDigest_Class
,
rb_mDigest_Instance
);
706
707
/* class methods */
708
rb_define_singleton_method
(
rb_cDigest_Class
,
"digest"
,
rb_digest_class_s_digest
, -1);
709
rb_define_singleton_method
(
rb_cDigest_Class
,
"hexdigest"
,
rb_digest_class_s_hexdigest
, -1);
710
711
id_metadata
=
rb_intern
(
"metadata"
);
712
713
/* class Digest::Base < Digest::Class */
714
rb_cDigest_Base
=
rb_define_class_under
(
rb_mDigest
,
"Base"
,
rb_cDigest_Class
);
715
716
rb_define_alloc_func
(
rb_cDigest_Base
,
rb_digest_base_alloc
);
717
718
rb_define_method
(
rb_cDigest_Base
,
"initialize_copy"
,
rb_digest_base_copy
, 1);
719
rb_define_method
(
rb_cDigest_Base
,
"reset"
,
rb_digest_base_reset
, 0);
720
rb_define_method
(
rb_cDigest_Base
,
"update"
,
rb_digest_base_update
, 1);
721
rb_define_method
(
rb_cDigest_Base
,
"<<"
,
rb_digest_base_update
, 1);
722
rb_define_private_method
(
rb_cDigest_Base
,
"finish"
,
rb_digest_base_finish
, 0);
723
rb_define_method
(
rb_cDigest_Base
,
"digest_length"
,
rb_digest_base_digest_length
, 0);
724
rb_define_method
(
rb_cDigest_Base
,
"block_length"
,
rb_digest_base_block_length
, 0);
725
}
726
Generated on Mon Sep 22 2014 11:05:21 for Ruby by
1.8.2