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