Objective C: SHA1

30,062

Solution 1

CommonCrypto (an Apple framework) has functions for calculating SHA-1 hashes, including a one-step hash:

#include <CommonCrypto/CommonDigest.h>

unsigned char digest[CC_SHA1_DIGEST_LENGTH];
NSData *stringBytes = [someString dataUsingEncoding: NSUTF8StringEncoding]; /* or some other encoding */
if (CC_SHA1([stringBytes bytes], [stringBytes length], digest)) {
    /* SHA-1 hash has been calculated and stored in 'digest'. */
    ...
}

For a set of numbers, let us assume you mean an array of ints of known length. For such data, it is easier to iteratively construct the digest rather than use the one-shot function:

unsigned char digest[CC_SHA1_DIGEST_LENGTH];
uint32_t *someIntegers = ...;
size_t numIntegers = ...;

CC_SHA1_CTX ctx;
CC_SHA1_Init(&ctx);
{
    for (size_t i = 0; i < numIntegers; i++)
        CC_SHA1_Update(&ctx, someIntegers + i, sizeof(uint32_t));
}
CC_SHA1_Final(digest, &ctx);

/* SHA-1 hash has been calculated and stored in 'digest'. */
...

Note that this does not take endianness into account. The SHA-1 calculated with this code on a PowerPC system will differ from the one calculated on an i386 or ARM system. The solution is simple--swap the bytes of the integers to a known endianness before doing the calculation:

    for (size_t i = 0; i < numIntegers; i++) {
        uint32_t swapped = CFSwapInt32HostToLittle(someIntegers[i]); /* or HostToBig */
        CC_SHA1_Update(&ctx, &swapped, sizeof(swapped));
    }

Solution 2

Another solution with a message digest library (nv-ios-digest):

(1) String

// Create an SHA1 instance, update it with a string and do final.
SHA1 sha1 = [SHA1 sha1WithString:@"Hello"];

// Get the pointer of the internal buffer that holds the message digest value.
// The life of the internal buffer ends when the SHA1 instance is discarded.
// Copy the buffer as necessary. The size of the buffer can be obtained by
// 'bufferSize' method.
unsigned char *digestAsBytes = [sha1 buffer];

// Get the string expression of the message digest value.
NSString *digestAsString = [sha1 description];

(2) Numbers

// Create an SHA1 instance.
SHA1 sha1 = [[SHA1 alloc] init];

// Update the SHA1 instance with numbers.
// (Sorry, the current implementation is endianness-dependent.)
[sha1 updateWithShort:(short)1];
[sha1 updateWithInt:(int)2];
[sha1 updateWithLong:(long)3];
[sha1 updateWithLongLong:(long long)4];
[sha1 updateWithFloat:(float)5];
[sha1 updateWithDouble:(double)6];

// Do final. 'final' method returns the pointer of the internal buffer
// that holds the message digest value. 'buffer' method returns the same.
// The life of the internal buffer ends when the SHA1 instance is discarded.
// Copy the buffer as necessary. The size of the buffer can be obtained by
// 'bufferSize' method.
unsigned char *digestAsBytes = [sha1 final];

// Get the string expression of the message digest value.
NSString *digestAsString = [sha1 description];

The message digest library supports MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512.

[Blog] Message digests (MD5, SHA1, etc.) on iOS with dedicated classes
http://darutk-oboegaki.blogspot.jp/2013/04/message-digests-md5-sha1-etc-on-ios.html

[Library] nv-ios-digest
https://github.com/TakahikoKawasaki/nv-ios-digest

Solution 3

SHA1 doesn't actually come with Objective-C. You can use the C source code for hashdeep and friends, which is licensed under the public domain (Because it was written by an employee of the United States government): http://md5deep.sourceforge.net/ .

Share:
30,062
Daniel
Author by

Daniel

Software &amp; Web Developer

Updated on July 30, 2022

Comments

  • Daniel
    Daniel almost 2 years

    How do i sha1 a string or set of numbers in Objective c?

  • schot
    schot almost 14 years
    Another option would be libgcrypt, from the makers of GnuPG (gnupg.org/related_software/libraries.en.html#lib-libgcrypt)‌​.
  • Daniel
    Daniel almost 14 years
    Is there any secure encryption that is supported directly for obj c and php?
  • Billy ONeal
    Billy ONeal almost 14 years
    @schot: But libcrypt has a much more restrictive license. @Daniel: Not out of the box, no. Objective-C does not come with much in the way of libraries.
  • Daniel
    Daniel almost 14 years
    Common Crypto is not apart of the SDK any more
  • Jonathan Grynspan
    Jonathan Grynspan almost 14 years
    As of 4.0.2, yes it is. Go ahead and try it!
  • ThomasW
    ThomasW about 13 years
    CommonCrypto, which includes SHA1, is included with iOS as mentioned in the checked answer.
  • Billy ONeal
    Billy ONeal about 13 years
    @ThomasW: Objective-C != iOS. The language is perfectly usable on any platform, even if Mac is the most common of the platforms where it is used.
  • Billy ONeal
    Billy ONeal about 13 years
    Of course, this is an iOS specific thing. It does not come with the Objective-C language.
  • Jonathan Grynspan
    Jonathan Grynspan about 13 years
    It's an Apple framework, yes, but technically NSString doesn't come with Objective-C either. Objective-C is just a syntax; everything else is implementation.
  • Jonathan Grynspan
    Jonathan Grynspan about 13 years
    Yes, but the vast vast vast majority of developers with any interest in Objective-C are interested in iOS or Mac development. std::string isn't a mandated part of C++ but there's nary a C++ developer out there who avoids it.
  • Billy ONeal
    Billy ONeal about 13 years
    @Jonathan: Actually, std::string is a mandated part of the C++ standard. Apple's libraries are not part of the Objective-C standard. If the OP wanted to talk about Apple's libraries, then he should have noted that in the question.
  • Jonathan Grynspan
    Jonathan Grynspan about 13 years
    He also didn't note he was working with a Turing-complete system. It's assumed.
  • Billy ONeal
    Billy ONeal about 13 years
    @Jonathan: The Objective-C standard mandates a Turing complete system. It does not mandate Apple's libraries. We have an iOS tag here for a reason.
  • ThomasW
    ThomasW about 13 years
    The author has clarified that he's looking for a Mac OS X solution.
  • smirkingman
    smirkingman over 12 years
    I had to use unsigned char digest... for this to compile.
  • A'sa Dickens
    A'sa Dickens almost 11 years
    i had to add the Security.Framework to the project , i thought it was libcommonCrypto.dylib , in case anyone else made that mistake