md5 a string multiple times - objective-c

md5 a string multiple times in Python:
def md5(i):
return hashlib.md5(i).hexdigest().upper()
def md5x3(src):
f = hashlib.md5(src).digest()
s = hashlib.md5(f).digest()
t = md5(s)
return t
how to implement above in C with OpenSSL on MacOS/iOS or in Objective-C without OpenSSL on MacOS/iOS ?
I'm try following, but its result is different from python's.
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
static char* hextostr(const unsigned char* in , int len)
{
char* res = (char*)malloc(len * 2 + 1);
int i = 0;
memset(res , 0 , len * 2 + 1);
while(i < len)
{
sprintf(res + i * 2 , "%02x" , in[i]);
i ++;
};
// i = 0;
// int reslength;
// reslength=(int)strlen(res);
// while(i < reslength)
// {
// res[i] = toupper(res[i]);
// i ++;
// };
return res;
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * foo = #"abcdefghij";
NSData * buf1 = [foo dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result1[CC_MD5_DIGEST_LENGTH];
CC_MD5([buf1 bytes], (unsigned int)[buf1 length], result1);
NSData * buf2 = [[[NSString alloc] initWithFormat:#"%s", result1] dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result2[CC_MD5_DIGEST_LENGTH];
CC_MD5(result1, (unsigned int)strlen(result1), result2);
NSData * buf3 = [[[NSString alloc] initWithFormat:#"%s", result2] dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result3[CC_MD5_DIGEST_LENGTH];
CC_MD5(result2, (unsigned int)strlen(result2), result3);
NSString * res = [[NSString alloc] initWithFormat:
#"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result3[0], result3[1], result3[2], result3[3], result3[4], result3[5], result3[6], result3[7],
result3[8], result3[9], result3[10], result3[11], result3[12], result3[13], result3[14], result3[15]
];
NSLog(#"%s", hextostr(result1, CC_MD5_DIGEST_LENGTH));
NSLog(#"%s", hextostr(result2, CC_MD5_DIGEST_LENGTH));
NSLog(#"%s", hextostr(result3, CC_MD5_DIGEST_LENGTH));
[pool drain];
return 0;
}

Use a digest library, such as OpenSSL, which you probably have installed already. See http://www.openssl.org/docs/crypto/md5.html. Source code for MD5 is available at http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html.

Related

parse const char* argv[]

Code:-
#import <Foundation/Foundation.h>
int main(int argc, const char* argv[]){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
char* charString = argv[1];
printf("%s", charString);
[pool drain];
return 0;
}
Problem:-
But the above line is printing null, how to get the array of integers;
argv[0] is the name of your program. If you want to read your parameters, start by reading argv[1]. Of course, you should also check that there are actually some parameters using argc > 1.
Or you could use [[NSProcessInfo processInfo] arguments]
int main(int argc, const char* argv[]){
#autoreleasepool {
for (NSInteger i = 0; i < argc; i++) {
NSString *stringArgument = [NSString stringWithFormat:#"%s", argv[i]];
NSLog(#"%#", stringArgument);
NSLog(#"Integer value: %i", [stringArgument intValue]);
}
}
return 0;
}
or
int main(int argc, const char* argv[]){
#autoreleasepool {
for (NSString *argument in [NSProcessInfo processInfo].arguments) {
NSLog(#"%#", argument);
NSLog(#"Integer value: %i", [argument intValue]);
}
}
return 0;
}
Arguments: 10 20
Output:
ObjcTest[65709:1964435] /Projects/ObjcTest/Build/Products/Debug/ObjcTest
ObjcTest[65709:1964435] Integer value: 0
ObjcTest[65709:1964435] 10
ObjcTest[65709:1964435] Integer value: 10
ObjcTest[65709:1964435] 20
ObjcTest[65709:1964435] Integer value: 20
Note the first argument cannot be converted to an integer therefore the printed value is 0.

string to int array in objective

Hi I trying to convert string to int array in objective C its running fine in xcode but give some error in editor http://ideone.com
I have input like = {1,2,3,4,5} and want to convert it into int array or NSARRAY in and print....
#import <Foundation/Foundation.h>
NSArray* sampleMethod(NSString*val){
NSString *stringWithoutbracketstart = [val stringByReplacingOccurrencesOfString:#"{" withString:#""];
NSString *stringWithoutbracketend = [stringWithoutbracketstart
stringByReplacingOccurrencesOfString:#"}" withString:#""];
NSLog(#"%#",stringWithoutbracketend);
NSArray *items=[[NSArray alloc]init];
items = [stringWithoutbracketend componentsSeparatedByString:#","];
//NSLog(#"%#",items);
return items;
}
int main(int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *value =#"{1,2,3}";
NSArray* ip1= sampleMethod(value);
NSLog(#"%#",ip1);
[pool drain];
return 0;
}
Why not make the input string valid JSON and then it can be arbitrarily extended with little coding effort (no effort at all with respect to parsing):
int main(int argc, const char **argv)
{
int retval = 0;
#autoreleasepool {
if (argc == 2) {
NSString *str = #(argv[1]);
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
if ([array isKindOfClass:[NSArray class]]) {
// Done
} else if (!array) {
NSLog(#"Input data is invalid: %#", [error localizedDescription]);
retval = 2;
} else {
NSLog(#"Input data is invalid");
retval = 3;
}
} else {
NSLog(#"Provide a JSON-list");
retval = 1;
}
}
return retval;
}
This means you would need to supply the list in JSON format:
$ ./myprog '[ 1, 2, 3 ]'
(quotes are necessary)
I found the solution easily by using your advice....
#import <Foundation/Foundation.h>
NSArray*sampleMethod(NSString*val){
NSString *newStr = [val substringFromIndex:1];
NSString *newStr1 = [newStr substringToIndex:[newStr length]-1];
NSArray *yourWords = [newStr1 componentsSeparatedByString:#","];
return yourWords;
}
int main(int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *value =#"{1,2,3}";
NSArray* ip1= sampleMethod(value);
NSLog(#"%#",ip1);
[pool drain];
return 0;
}

CBCMac (DESede) implementation in objective c

Has any one implemented CBC Mac (DESede) in Objective c? Could you show sample code or explain how to correct my code?
Here is my effort so far....
-(void)tryMac
{
unsigned char blockCount;
unsigned char key[16] = "\x1\x2\x3\x4\x5\x6\x7\x8\x9\x0\x1\x2\x3\x4\x5\x6";
unsigned char data[16] = "\x54\x68\x69\x73\x69\x73\x6d\x79\x73\x74\x72\x69\x6e\x67\x0\x0";
DES_cblock *desKey1 = (DES_cblock* ) key;
DES_cblock *desKey2 = (DES_cblock* ) key;
unsigned char *iv = (unsigned char *) malloc(8);
memset(iv, 0x0, 8);
DES_set_odd_parity(desKey1);
DES_set_odd_parity(desKey2);
DES_key_schedule schedule1;
DES_key_schedule schedule2;
DES_set_key_checked(desKey1, &schedule1);
DES_set_key_checked(desKey2, &schedule2);
int len = sizeof(data);
blockCount = len / 4;
int lastBlock = 0;
for(unsigned char i = 0; i < blockCount; i++)
{
int bufferLen = sizeof(data)/blockCount;
unsigned char buffer[bufferLen];
memccpy(buffer, data, lastBlock, bufferLen);
lastBlock = (i + 1) * bufferLen;
unsigned char *result = (unsigned char *) malloc(4);
if (lastBlock == len)
{
DES_ede2_cbc_encrypt(buffer, result, bufferLen, &schedule1, &schedule2, (DES_cblock *) iv, DES_ENCRYPT);
NSData *encryptedData = [NSData dataWithBytes:(const void *)result length:4];
NSString *encryptedString = [self stringWithHexFromData:encryptedData];
NSLog(#"Encrypted Block %#",encryptedString);
}
}

Equivalent Hashing in C# and Objective-C using HMAC256

I'm working with a partner and we're not able to get C# and Objective-C to produce the same hashes using what we think are the same tools in the respective languages. In C#, I'm doing this:
byte[] noncebytes=new byte[32];
//We seed the hash generator with a new 32 position array. Each position is 0.
//In prod code this would be random, but for now it's all 0s.
HMACSHA256 hmac256 = new HMACSHA256(noncebytes);
string plaintext = "hello";
string UTFString = Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(plaintext));
string HashString = Convert.ToBase64String(
hmac256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(plaintext))); //Convert that hash to a string.
This produces the following base64string hash:
Q1KybjP+DXaaiSKmuikAQQnwFojiasyebLNH5aWvxNo=
What is the equivalent Objective-C code to do this? We need the client and the server to be able to generate matching hashes for matching data.
Here is the Objective-C code we are currently using:
...
NSData *zeroNumber = [self zeroDataWithBytes:32]; //empty byte array
NSString *nonceTest = [zeroNumber base64String]; // using MF_Base64Additions.h here
NSData *hashTest = [self hmacForKeyAndData:nonceTest withData:#"hello"]; //creating hash
NSString *hashTestText = [hashTest base64String];
NSLog(#"hello hash is %#", hashTestText);
...
//functions for zeroing out the byte. I'm sure there's a better way
- (NSData *)zeroDataWithBytes: (NSUInteger)length {
NSMutableData *mutableData = [NSMutableData dataWithCapacity: length];
for (unsigned int i = 0; i < length; i++) {
NSInteger bits = 0;
[mutableData appendBytes: (void *) &bits length: 1];
} return mutableData;
}
//hash function
-(NSData *) hmacForKeyAndData:(NSString *)key withData:(NSString *) data {
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
UPDATE:
There is a pretty good project on GitHub that seems to accomplish everything you want, plus a lot more encryption related options; includes unit tests.
NSData *hmacForKeyAndData(NSString *key, NSString *data)
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
(Source)
With the above, I think you will have import <CommonCrypto/CommonHMAC.h>. The next step for encoding to Base64:
+ (NSString *)Base64Encode:(NSData *)data
{
//Point to start of the data and set buffer sizes
int inLength = [data length];
int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
const char *inputBuffer = [data bytes];
char *outputBuffer = malloc(outLength);
outputBuffer[outLength] = 0;
//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//start the count
int cycle = 0;
int inpos = 0;
int outpos = 0;
char temp;
//Pad the last to bytes, the outbuffer must always be a multiple of 4
outputBuffer[outLength-1] = '=';
outputBuffer[outLength-2] = '=';
/* http://en.wikipedia.org/wiki/Base64
Text content M a n
ASCII 77 97 110
8 Bit pattern 01001101 01100001 01101110
6 Bit pattern 010011 010110 000101 101110
Index 19 22 5 46
Base64-encoded T W F u
*/
while (inpos < inLength){
switch (cycle) {
case 0:
outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
cycle = 1;
break;
case 1:
temp = (inputBuffer[inpos++]&0x03)<<4;
outputBuffer[outpos] = Encode[temp];
cycle = 2;
break;
case 2:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
temp = (inputBuffer[inpos++]&0x0F)<<2;
outputBuffer[outpos] = Encode[temp];
cycle = 3;
break;
case 3:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
cycle = 4;
break;
case 4:
outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
cycle = 0;
break;
default:
cycle = 0;
break;
}
}
NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
free(outputBuffer);
return pictemp;
}
Note the second line of code in the objective-c portion of the question.
NSString *nonceTest = [zeroNumber base64String];
but it should be this:
NSString *nonceTest = [[NSString alloc] initWithData:zeroNumber encoding:NSASCIIStringEncoding];
It was a case of converting the string to base64 when we didn't need to for the hmac seeeding.
We now get: Q1KybjP+DXaaiSKmuikAQQnwFojiasyebLNH5aWvxNo= as the hash on both platforms.

Converting binary bits to Hex value

How do I convert binary data to hex value in obj-c?
Example:
1111 = F,
1110 = E,
0001 = 1,
0011 = 3.
I have a NSString of 10010101010011110110110011010111, and i want to convert it to hex value.
Currently I'm doing in a manual way. Which is,
-(NSString*)convertToHex:(NSString*)hexString
{
NSMutableString *convertingString = [[NSMutableString alloc] init];
for (int x = 0; x < ([hexString length]/4); x++) {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
NSString *A = [NSString stringWithFormat:#"%c", [hexString characterAtIndex:(x)]];
NSString *B = [NSString stringWithFormat:#"%c", [hexString characterAtIndex:(x*4+1)]];
NSString *C = [NSString stringWithFormat:#"%c", [hexString characterAtIndex:(x*4+2)]];
NSString *D = [NSString stringWithFormat:#"%c", [hexString characterAtIndex:(x*4+3)]];
if ([A isEqualToString:#"1"]) { a = 8;}
if ([B isEqualToString:#"1"]) { b = 4;}
if ([C isEqualToString:#"1"]) { c = 2;}
if ([D isEqualToString:#"1"]) { d = 1;}
int total = a + b + c + d;
if (total < 10) { [convertingString appendFormat:#"%i",total]; }
else if (total == 10) { [convertingString appendString:#"A"]; }
else if (total == 11) { [convertingString appendString:#"B"]; }
else if (total == 12) { [convertingString appendString:#"C"]; }
else if (total == 13) { [convertingString appendString:#"D"]; }
else if (total == 14) { [convertingString appendString:#"E"]; }
else if (total == 15) { [convertingString appendString:#"F"]; }
}
NSString *convertedHexString = convertingString;
return [convertedHexString autorelease];
[convertingString release];
}
Anyone have better suggestion? This is taking too long.
Thanks in advance.
I have never been much of a C hacker myself, but a problem like this is perfect for C, so here is my modest proposal - coded as test code to run on the Mac, but you should be able to copy the relevant bits out to use under iOS:
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
NSString *str = #"10010101010011110110110011010111";
char* cstr = [str cStringUsingEncoding: NSASCIIStringEncoding];
NSUInteger len = strlen(cstr);
char* lastChar = cstr + len - 1;
NSUInteger curVal = 1;
NSUInteger result = 0;
while (lastChar >= cstr) {
if (*lastChar == '1')
{
result += curVal;
}
/*
else
{
// Optionally add checks for correct characters here
}
*/
lastChar--;
curVal <<= 1;
}
NSString *resultStr = [NSString stringWithFormat: #"%x", result];
NSLog(#"Result: %#", resultStr);
[p release];
}
It seems to work, but I am sure that there is still room for improvement.
#interface bin2hex : NSObject
+(NSString *)convertBin:(NSString *)bin;
#end
#implementation bin2hex
+(NSString*)convertBin:(NSString *)bin
{
if ([bin length] > 16) {
NSMutableArray *bins = [NSMutableArray array];
for (int i = 0;i < [bin length]; i += 16) {
[bins addObject:[bin substringWithRange:NSMakeRange(i, 16)]];
}
NSMutableString *ret = [NSMutableString string];
for (NSString *abin in bins) {
[ret appendString:[bin2hex convertBin:abin]];
}
return ret;
} else {
int value = 0;
for (int i = 0; i < [bin length]; i++) {
value += pow(2,i)*[[bin substringWithRange:NSMakeRange([bin length]-1-i, 1)] intValue];
}
return [NSString stringWithFormat:#"%X", value];
}
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
// insert code here...
NSLog(#"0x%#",[bin2hex convertBin:#"10010101010011110110110011010111"]);
}
return 0;
}
I get the result of 0x954F6CD7 for 10010101010011110110110011010111 and it seems to be instant
Maybe easiest would be to setup a NSDictionary for quick lookups?
[NSDictionary dictionaryWithObjects...]
since it is a limited number of entries.
"0000" -> 0
...
"1111" -> F