0

I have a requirement to integrate with a web service that serves as a login. The hash needs to be generated on the client. I am able to produce the correct hash as NSMutableData, but then I need to convert it to a string, without the spaces or brackets produced when the NSMutableData object is rendered as a string in the output console. I have read several posts, all seeming to say the same thing:


NSString *newstring = [[NSString alloc] initWithDSata:dataToConvert  encoding:NSUTF8StringEncoding];

Unfortunately, this doesnt work for me. Using NSUTF8StringEncoding returns null. NSASCIIStringEncoding is even worse.

Here is my code:


    NSString *password = [NSString stringWithFormat:@"%@%@", kPrefix, [self.txtPassword text]];
    NSLog(@"PLAIN: %@", password);

    NSData *data = [password dataUsingEncoding:NSASCIIStringEncoding];
    NSMutableData *sha256Out = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(data.bytes, data.length, sha256Out.mutableBytes);
    NSString *preppedPassword = [[NSString alloc] initWithData:sha256Out encoding:NSASCIIStringEncoding];
    NSLog(@"HASH: %@\n", preppedPassword);

How can I convert the NSMutableData to string?

My problem is that I need to from this

<7e8df5b3 17c99263 e4fe6220 bb75b798 4a41de45 44464ba8 06266397 f165742e>

to this

7e8df5b317c99263e4fe6220bb75b7984a41de4544464ba806266397f165742e

Pheepster
  • 6,045
  • 6
  • 41
  • 75

1 Answers1

0

See How to convert an NSData into an NSString Hex string?

I use a slightly modified version myself:

@implementation NSData (Hex)

- (NSString *)hexRepresentationWithSpaces:(BOOL)spaces uppercase:(BOOL)uppercase {
    const unsigned char *bytes = (const unsigned char *)[self bytes];
    NSUInteger nbBytes = [self length];
    // If spaces is true, insert a space every this many input bytes (twice this many output characters).
    static const NSUInteger spaceEveryThisManyBytes = 4UL;
    // If spaces is true, insert a line-break instead of a space every this many spaces.
    static const NSUInteger lineBreakEveryThisManySpaces = 4UL;
    const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces;
    NSUInteger strLen = 2 * nbBytes + (spaces ? nbBytes / spaceEveryThisManyBytes : 0);

    NSMutableString *hex = [[NSMutableString alloc] initWithCapacity:strLen];

    for (NSUInteger i = 0; i < nbBytes; ) {
        if (uppercase) {
            [hex appendFormat:@"%02X", bytes[i]];
        } else {
            [hex appendFormat:@"%02x", bytes[i]];
        }
        // We need to increment here so that the every-n-bytes computations are right.
        ++i;

        if (spaces) {
            if (i % lineBreakEveryThisManyBytes == 0) {
                [hex appendString:@"\n"];
            } else if (i % spaceEveryThisManyBytes == 0) {
                [hex appendString:@" "];
            }
        }
    }
    return hex;
}

@end
Community
  • 1
  • 1
leafduo
  • 144
  • 1
  • 5
  • This might be a real newbie comment, but when I use this, my hash is returned in all caps. How can I make it NOT do that? – Pheepster Apr 25 '13 at 21:42
  • The original version returns hashes in all caps, I added an argument (uppercase) in my version to control that. – leafduo Apr 25 '13 at 21:49