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
|
# File 'ext/cobreak/cobreak_gcrypt.c', line 52
VALUE double_sha1_hexdigest(VALUE self, VALUE full) {
char *str = RSTRING_PTR(full);
int length = RSTRING_LEN(full); // Obtener la longitud de la cadena
gcry_md_hd_t handle;
unsigned char digest[20]; // SHA-1 produce un hash de 20 bytes
unsigned char intermediate_digest[20]; // Para almacenar el primer hash
char out[41]; // 20 bytes * 2 para hexadecimal + 1 para el terminador
// Inicializar la biblioteca libgcrypt
if (!gcry_check_version(GCRYPT_VERSION)) {
rb_raise(rb_eRuntimeError, "VersiĆ³n de libgcrypt no compatible.");
}
// Abrir el contexto de hash para SHA-1
gcry_md_open(&handle, GCRY_MD_SHA1, 0);
// Actualizar el hash con la cadena de entrada
gcry_md_write(handle, str, length);
// Finalizar el hash y obtener el primer resultado
memcpy(intermediate_digest, gcry_md_read(handle, GCRY_MD_SHA1), 20);
gcry_md_close(handle);
// Abrir un nuevo contexto de hash para el segundo SHA-1
gcry_md_open(&handle, GCRY_MD_SHA1, 0);
// Actualizar el hash con el resultado del primer hash
gcry_md_write(handle, intermediate_digest, 20);
// Finalizar el hash y obtener el resultado final
memcpy(digest, gcry_md_read(handle, GCRY_MD_SHA1), 20);
gcry_md_close(handle);
// Convertir el hash a una cadena hexadecimal
for (int n = 0; n < 20; ++n) {
sprintf(&(out[n * 2]), "%02x", (unsigned int)digest[n]);
}
out[40] = '\0'; // Terminar la cadena
VALUE result = rb_str_new2(out); // Crear una nueva cadena Ruby
return result;
}
|