¿Cómo puedo crear un SHA1 de un NSString.

Digamos que el NSString se configura como:

NSString *message = @"Message";

Puedo usar PHP para crear un hash SHA1 con sha($message). Pero lamentablemente no funciona así que dentro de Objective-C.

  • Usted puede buscar en CC_SHA1. Véase también here
  • Gracias Alex, Que trabajó para mí!
  • Si esa era la respuesta, debe contabilizar como una respuesta para otras Alex tiene algo para aceptar.
  • Definitivamente post como respuesta!
  • Hecho! (fillerfiller)

8 Comentarios

  1. 90

    Tengo esto en una categoría en la NSString (disponible en https://github.com/hypercrypt/NSString-Hashes):

    #import <CommonCrypto/CommonDigest.h>
    
    ...
    
    - (NSString *)sha1
    {
        NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
        uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    
        CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
    
        NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    
        for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        {
            [output appendFormat:@"%02x", digest[i]];
        }
    
        return output;
    }

    Comenzando con Xcode 10.0, usted debe utilizar import CommonCrypto lugar, ya que ahora está disponible de forma nativa en Swift! Si han emigrado recientemente a Xcode 10.0 y utilizar el enfoque antiguo, este puede ser tu señal para realizar el cambio:

    Comando CompileSwift falló con un código de salida distinto de cero

    • No que requieren de la importación de <CommonCrypto/CommonDigest.h>?
    • Buen punto, se olvidó de copiar y pegar… (respuesta mejorada)
    • Xcode 4 se queja acerca de la línea: CC_SHA1(de datos.bytes de datos.longitud, digerir); Reemplazar con: CC_SHA1(de datos.bytes, (CC_LONG) de datos.longitud, digerir);
    • ¿Por qué se inicio el mutableString con CC_SHA1_DIGEST_LENGTH*2 y no solo [NSMutableString cadena] ?
    • Se crea una variable de cadena con capacidad suficiente para contener toda la cadena de salida, de tal manera que la cadena de almacenamiento no deben ser ampliados durante el bucle. Por lo general es mejor utilizar el *WithCapacity: métodos para la NSMutable* clases si usted sabe el tamaño que usted necesita antes de un bucle (o un límite superior) como el correcto tamaño de la memoria a continuación, puede asignarse al inicio.
  2. 16

    Me gusta bastante hypercrypt la respuesta, pero me han animado a publicar mi comentario.

    Usted puede mirar CC_SHA1, o este relacionados con LO pregunta.

  3. 12
    - (NSString *)sha1:(NSString *)str {
    const char *cStr = [str UTF8String];
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(cStr, strlen(cStr), result);
    NSString *s = [NSString  stringWithFormat:
               @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
               result[0], result[1], result[2], result[3], result[4],
               result[5], result[6], result[7],
               result[8], result[9], result[10], result[11], result[12],
               result[13], result[14], result[15],
               result[16], result[17], result[18], result[19]
               ];
    
    return s;
    }
  4. 6

    Me gusta hypercrypt la respuesta de lo mucho que me empaquetado en un pequeño repositorio git. Echa un vistazo a la categoría NSString
    en Github.

    También siéntase libre de añadir a ella con cualquier otro bien NSString Crypto

  5. 4

    Me tomó un tiempo para port @hypercrypt solución a Swift, así que me he decidido a compartir con otros que puedan tener el mismo problema.

    Una cosa importante a tener en cuenta es que usted necesita CommonCrypto de la biblioteca, pero que la biblioteca no tiene Swift módulo. La solución más sencilla es la importación en su puente de encabezado:

    #import <CommonCrypto/CommonCrypto.h>

    Una vez importados allí, usted no necesita nada más. Sólo el uso de la Cadena de extensión de siempre:

    extension String
    {
        func sha1() -> String
        {
            var selfAsSha1 = ""
    
            if let data = self.dataUsingEncoding(NSUTF8StringEncoding)
            {
                var digest = [UInt8](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
                CC_SHA1(data.bytes, CC_LONG(data.length), &digest)
    
                for index in 0..<CC_SHA1_DIGEST_LENGTH
                {
                    selfAsSha1 += String(format: "%02x", digest[Int(index)])
                }
            }
    
            return selfAsSha1
        }
    }

    Cuenta de que mi solución no surtirá efecto de la reserva de capacidad de lo que NSMutableString tiene en el post original. Sin embargo, tengo la duda de que nadie va a ver la diferencia 🙂

    • Muy bonito, pero ¿por qué una extensión?
    • Bien, principalmente porque la respuesta original usada de la Categoría, por lo que el común de la asociación, en mi cabeza estaba Extensión 🙂 creo que es bastante fácil y sólo se agrega la funcionalidad necesaria para la Cadena. Estoy abierto a soluciones mejores 🙂
  6. 3

    intente esto:

    #import <CommonCrypto/CommonDigest.h>
    
    -(NSData *) selector
    {
        unsigned char hashBytes[CC_SHA1_DIGEST_LENGTH];
        CC_SHA1([dataToHash bytes], [dataToHash length], hashBytes);
        NSData *data = [[NSData alloc] initWithBytes:hashBytes length:CC_SHA1_DIGEST_LENGTH];
    }
  7. 1

    Aquí una concisa y muy optimizado NSString categoría:

    @implementation NSString (PMUtils)
    - (NSString *)sha1Hash
    {
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSData *hash = [data sha1Hash];
    return [hash hexString];
    } 
    @end
    @implementation NSData (PMUtils)
    - (NSString *) hexString
    {
    NSUInteger bytesCount = self.length;
    if (bytesCount) {
    static char const *kHexChars = "0123456789ABCDEF";
    const unsigned char *dataBuffer = self.bytes;
    char *chars = malloc(sizeof(char) * (bytesCount * 2 + 1));
    char *s = chars;
    for (unsigned i = 0; i < bytesCount; ++i) {
    *s++ = kHexChars[((*dataBuffer & 0xF0) >> 4)];
    *s++ = kHexChars[(*dataBuffer & 0x0F)];
    dataBuffer++;
    }
    *s = '\0';
    NSString *hexString = [NSString stringWithUTF8String:chars];
    free(chars);
    return hexString;
    }
    return @"";
    }
    - (NSData *)sha1Hash
    {
    unsigned char digest[CC_SHA1_DIGEST_LENGTH];
    if (CC_SHA1(self.bytes, (CC_LONG)self.length, digest)) {
    return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
    }
    return nil;
    }
    @end
  8. 1

    Estoy viendo un par de diferentes posibles mejoras a las respuestas en este post.

    1. No hacer nunca que una unprefixed categoría. Lo que si se implementa -[NSString sha1Hash] en su biblioteca, y otro de la biblioteca en la misma aplicación implementa el mismo método con un poco diferentes semántica? Cuál es el utilizado será aleatoria, y conducir a lo difícil de diagnosticar errores.
    2. Si desea una cadena, hay base64-codificación en la biblioteca estándar de hoy en día. Menos trabajo que manualmente edificio hexagonal stringification.

    Aquí está mi solución, adaptación de la excelente SocketRocket de la biblioteca SRHash.m:

    //NSString+Sha1Digest.h
    #import <Foundation/Foundation.h>
    @interface NSString (LBDigest)
    - (NSString *)lb_digestString;
    @end
    @interface NSData (LBDigest)
    - (NSString *)lb_digestString;
    @end
    //NSString+SHA1Digest.m
    #import "NSString+Sha1Digest.h"
    #import <CommonCrypto/CommonDigest.h>
    static NSData *LBSHA1HashFromBytes(const char *bytes, size_t length)
    {
    uint8_t outputLength = CC_SHA1_DIGEST_LENGTH;
    unsigned char output[outputLength];
    CC_SHA1(bytes, (CC_LONG)length, output);
    return [NSData dataWithBytes:output length:outputLength];
    }
    static NSData *LBSHA1HashFromString(NSString *string)
    {
    size_t length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
    return LBSHA1HashFromBytes(string.UTF8String, length);
    }
    @implementation NSData (LBDigest)
    - (NSString *)lb_digestString;
    {
    return [LBSHA1HashFromBytes(self.bytes, self.length) base64EncodedStringWithOptions:0];
    }
    @end
    @implementation NSString (LBDigest)
    - (NSString *)lb_digestString;
    {
    return [LBSHA1HashFromString(self) base64EncodedStringWithOptions:0];
    }
    @end

Dejar respuesta

Please enter your comment!
Please enter your name here