Class: CoBreak::GCrypt::DOUBLE_SHA1

Inherits:
Object
  • Object
show all
Defined in:
ext/cobreak/cobreak_gcrypt.c

Class Method Summary collapse

Class Method Details

.hexdigest(full) ⇒ Object



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;
}