2

According to my requirement:

  1. The input string has to be converted into Byte Values.
  2. Each character of string , which are 16 bit values , has to be converted to low 8 bits.
  3. The Sha1 is then computed over the byte Array.
  4. The resulting SHA-1 is converted into a 40 character string.

I know how to convert a string into SHA1 , but the rest of part is a bit gloomy to me. I have been able to do the last two steps.

unsigned char digest[CC_SHA1_DIGEST_LENGTH];
NSData *dataString = [yourString dataUsingEncoding: NSUTF8StringEncoding]; 

if (CC_SHA1([dataString bytes], [dataString length], digest)) {
   //Sha1 is calculated & stored in digest.
}

Any help will be appreciated.

rmaddy
  • 314,917
  • 42
  • 532
  • 579

4 Answers4

11

I have created this function , which works fine according to your requirement . You just have to input a string.

#import <CommonCrypto/CommonDigest.h>

- (NSString *)calculateSHA:(NSString *)yourString
{
    const char *ptr = [yourString UTF8String];

    int i =0;
    int len = strlen(ptr);
    Byte byteArray[len];
    while (i!=len)
    {
        unsigned eachChar = *(ptr + i);
        unsigned low8Bits = eachChar & 0xFF;

        byteArray[i] = low8Bits;
        i++;
    }


    unsigned char digest[CC_SHA1_DIGEST_LENGTH];

    CC_SHA1(byteArray, len, digest);

    NSMutableString *hex = [NSMutableString string];
    for (int i=0; i<20; i++)
        [hex appendFormat:@"%02x", digest[i]];

    NSString *immutableHex = [NSString stringWithString:hex];

    return immutableHex;
}

Then you just have to call the above method.

[self calculateSHA:yourString];
Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195
Abhishek Singh
  • 6,068
  • 1
  • 23
  • 25
  • I do not understand what the while-loop is for. `const char *ptr = [yourString UTF8String]` is a sequence of bytes, truncating these bytes to 8-bit does not make any difference. – Martin R Mar 18 '13 at 19:53
  • yeah .. in discussion .. he wanted the method 2 truncate it ... so just provided...Rod ..according to requirement .. He Needed it..ur method is also fine. – Abhishek Singh Mar 19 '13 at 07:57
  • It is fine if that is what Rod needed, I have no problem with that! - But the while-loop does not truncate anything (`ptr` is a pointer to *bytes*!!). So you could just remove the while-loop, that would not make any difference to the result. - My code truncates 16-bit characters to 8-bit, and your code converts 16-bit characters to UTF-8, that is something different. But as I said, I have no problem with your answer being accepted, I just wondered about the unnecessary code. – Martin R Mar 19 '13 at 08:10
1
NSData *dataString = [yourString dataUsingEncoding: NSUTF8StringEncoding];

converts the string to UTF-8 bytes, e.g. "é" = Unicode 00E9 is converted to the two bytes C3 A9, and "€" = Unicode 20AC is converted to three bytes E2 82 AC.

If your requirement is to "truncate" the Unicode characters to the lower 8 bits, you have to do this "manually", I do not know a built-in encoding that could be used for that:

NSMutableData *dataString = [NSMutableData dataWithLength:[yourString length]];
uint8_t *dataBytes = [dataString mutableBytes];
for (NSUInteger i = 0; i < [yourString length]; i++) {
    // assigning the character to a uint_8 truncates to the lower 8 bit:
    dataBytes[i] = [yourString characterAtIndex:i];
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
0

Based on your code snippet, you want to do something like:

unsigned char digest[CC_SHA1_DIGEST_LENGTH];
NSData *dataString = [yourString dataUsingEncoding: NSUTF8StringEncoding];
NSMutableString *outString;

if (CC_SHA1([dataString bytes], [dataString length], digest)) {
    for (int i=0;i<CC_SHA1_DIGEST_LENGTH;i++) {
        [outString appendFormat:@"%02x", digest[i]];
    }
}

Where outString will be your 40-char string.

Mobile Ben
  • 7,121
  • 1
  • 27
  • 43
0

Here's an NSString category for creating a SHA1 hash of an NSString. Creating SHA1 Hash from NSString

Community
  • 1
  • 1
Peter
  • 2,005
  • 1
  • 20
  • 14