I have an application in which when I enter emailid,then emailid is converted into array of integers using md5 digest.
I have written the code for converting into array but the array is not getting generated in proper format. This is format which I need:
[2, -88, 14, -36, -128, -124, -32, -91, 0, 107, -41, -114, -118, 100,
-45, 45];
but my code is not retiring in this format.
This is my code:
static NSData* digest(NSData *data, unsigned char* (*cc_digest)(const void*, CC_LONG, unsigned char*), CC_LONG digestLength)
{
unsigned char md[digestLength];
(void)cc_digest([data bytes], [data length], md);
NSData* data1 = [NSData dataWithBytes:(const void *)md length:sizeof(unsigned char)*digestLength];
return [NSData dataWithBytes:md length:digestLength];
}
- (NSData *) md5
{
NSString *str =#"mitalee.yadav#gmail.com";
NSData *data = [str dataUsingEncoding:NSASCIIStringEncoding];
return digest(data, CC_MD5, CC_MD5_DIGEST_LENGTH);
}
in my appdidfinishlaunching I'm doing this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSData *dat = [self md5];
NSUInteger len = [dat length];
Byte *byteData= (Byte*)malloc(len);
[dat getBytes:byteData length:len];
}
but this is returning bytes in this format
<02a80edc 8084e0a5 006bd78e 8a64d32d>
Loop your byte array and do follow on it..
int result[16];
for(int i = 0; i < 16; i++)
{
Byte b = byteData[i];//0xDC;
result[i] = (b & 0x80) > 0 ? b - 0xFF -1 : b;
}
This will convert byte into signed int. I am sure that there must be optimised way.
Related
I have a string variable in iOS and I would like to convert that to a character array and then to a hex bytes like 0xD6, 0xD6 etc.
It will be great if there is a library in Objective-C that I can use for this
swift 4
string to byte:
let strChar = "A"
let data1 = [UInt8](self.strChar.utf8)
may be answer is here:
string to chars:
NSString *s = #"Some string";
const char *c = [s UTF8String];
chars to hex:
- (NSData *)dataFromHexString {
const char *chars = [self UTF8String];
int i = 0, len = self.length;
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
reference:NSString (hex) to bytes
I have the following category method on NSData. I'm trying to extract the bit field at the given index and have it return as an NSNumber. I have it working perfectly for all positive but I need it to work with negative numbers as well.
My Implementation looks as follows:
#import <Foundation/Foundation.h>
#interface NSData (ExternalDevices)
#end
#implementation NSData (ExternalDevices)
- (NSNumber *)extractLittleEndianBitFieldAtIndex:(int)index forLength:(int)length
{
//This function has limitations on the "length" parameter that are not yet know/defined
//These limitations are due to the max size of "NSInteger intData" defined below
int first_byte = index/8; //Index of the first byte containing this bit field
int last_byte = (length+index-1)/8; //Index of the last byte containing this bit field
int byte_length = last_byte - first_byte + 1; //number of bytes containing this bit field
Byte *byteArray = (Byte*)malloc(byte_length);
memcpy(byteArray, [[self subdataWithRange:NSMakeRange(first_byte, byte_length)] bytes], byte_length);
NSInteger intData = *((NSInteger *)byteArray);
free(byteArray);
return [NSNumber numberWithInt:intData];
}
+ (NSData *)dataFromHexString:(NSString *)string
{
string = [string lowercaseString];
NSMutableData *data= [NSMutableData new];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i = 0;
NSUInteger length = string.length;
while (i < length-1) {
char c = [string characterAtIndex:i++];
if (c < '0' || (c > '9' && c < 'a') || c > 'f')
continue;
byte_chars[0] = c;
byte_chars[1] = [string characterAtIndex:i++];
whole_byte = strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
return data;
}
#end
#interface Testing:NSObject
#end
#implementation Testing
- (instancetype)init
{
self = [super init];
if (self)
{
{
NSData *data = [NSData dataFromHexString:#"e30b"];
NSLog(#"%# should be 3043", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:#"46e0"];
NSLog(#"%# should be -8122", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:#"f208"];
NSLog(#"%# should be 2290", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:#"10e6"];
NSLog(#"%# should be -6640", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:#"018900"];
NSLog(#"%# should be 137", [data extractLittleEndianBitFieldAtIndex:8 forLength:16]);
}
}
return self;
}
#end
int main(int argc, char *argv[]) {
#autoreleasepool {
[[Testing alloc] init];
}
}
The following website seems to always yield the results I want under INT16 - Little Endian (BA)
http://www.scadacore.com/field-applications/miscellaneous/online-hex-converter.html
Although it is important to note that not every number I work with will be an INT16
Your line:
NSInteger intData = *((NSInteger *)byteArray);
is your key problem for two reasons:
byteArray may be shorter (or less likely, longer) than an NSInteger and you'll end up reading garbage. E.g. if byteArray is 2 bytes as in your examples and NSInteger is 4 bytes - which it will be in 64-bit - you'll read two bytes of garbage.
If you are converting signed values you need to sign-extend the value - that is replicate the sign bit into the higher unused bits. E.g. if you are converting a signed 16-bit field into a 32-bit signed value then the upper 16-bits need to be a replication of the most significant bit of the 16-bit value, so 0x7000 -> 0x00007000 and 0x8000 -> 0xFFFF8000.
You need to come up with an algorithm that handles these issues. You may find it easier to do the conversion a byte at a time using masking (and'ing), or'ing and shifting.
HTH
I have one quick question...
I am building a social media network site app and I need to hash the password NSString. How would I accomplish this? I have the password field on the app and would like to hash the string and encode it in SHA512 for the POST request.
Thanks in advance,
TechnologyGuy
Already answered: hash a password string using SHA512 like C#
But here's the copy-pasted code:
#include <CommonCrypto/CommonDigest.h>
+ (NSString *) createSHA512:(NSString *)source {
const char *s = [source cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData = [NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA512_DIGEST_LENGTH] = {0};
CC_SHA512(keyData.bytes, keyData.length, digest);
NSData *out = [NSData dataWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
return [out description];
}
Or if you prefer a hashed output, try this:
+(NSString *)createSHA512:(NSString *)string
{
const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:string.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:#"%02x", digest[i]];
return output;
}
+ (NSData *)sha512:(NSData *)data {
unsigned char hash[CC_SHA512_DIGEST_LENGTH];
if ( CC_SHA512([data bytes], [data length], hash) ) {
NSData *sha1 = [NSData dataWithBytes:hash length:CC_SHA512_DIGEST_LENGTH];
return sha1;
}
return nil;
}
Put this in a category on NSData, or use it whatever way you like, the code remains the same.
You should've researched your question. I found an answer in one google search.
I need to represent a NSInteger and NSString into array of bytes. below are the sample of what I am looking for.
For how, this harcodings are working fine. I want to do this through code. Any clue.
First, NSInteger into bytes of Hex:
NSInteger test = 1;
unsigned char byte[] = { 0x00, 0x01 };
NSInteger test = 16;
unsigned char byte[] = { 0x00, 0x10 };
NSData *data = [NSData dataWithBytes:byte length:sizeof(byte)];
Second, NSString into bytes of Hex:
NSString *test = #"31C5B562-BD07-4616-BCBD-130BA6822790";
unsigned char byte[] = {0x31, 0xC5, 0xB5, 0x62, 0xBD, 0x07, 0x46, 0x16, 0xBC, 0xBD, 0x13, 0x0B, 0xA6, 0x82, 0x27, 0x90};
NSData *data = [NSData dataWithBytes:byte length:sizeof(byte)];
I tried with below code and it works well for my UUID but for NSInteger to to be working I need to send "0010" instead of 16 and "0001" instead of 1. So any clue on how to do this conversion.
- (NSData *)hexData {
NSMutableData *hexData = [NSMutableData data];
int idx = 0;
for (idx = 0; idx+2 <= self.length; idx+=2) {
NSRange range = NSMakeRange(idx, 2);
NSString* hexStr = [self substringWithRange:range];
NSScanner* scanner = [NSScanner scannerWithString:hexStr];
unsigned int intValue;
[scanner scanHexInt:&intValue];
[hexData appendBytes:&intValue length:1];
}
return hexData;
}
EDIT:
int8_t test = -59;
int8_t bytes = CFSwapInt16HostToBig(test);
NSData *data1 = [NSData dataWithBytes:&bytes length:sizeof(bytes)];
Reaching as 0xFF instead of 0xC4
Since your string is a UUID string you can do something like this:
NSString *test = #"";
uuid_t uuid;
uuid_parse([test UTF8String], uuid)
NSData *data = [NSData dataWithBytes:uuid length:16];
For the number you can do:
NSInteger test = 1;
NSData *data = [NSData dataWithBytes:&test length:sizeof(test)];
Keep in mind that NSInteger is probably more than two bytes and you may also need to worry about byte order.
Update: Since it seems you need the integer value to be two bytes, you should do:
uint16_t test = 1;
NSData *data = [NSData dataWithBytes:&test length:sizeof(test)];
This will ensure 2 bytes. You also need to worry about byte ordering so you really need:
uint16_t test = 1;
uint16_t bytes = CFSwapInt16HostToBig(test);
NSData *data = [NSData dataWithBytes:&bytes length:sizeof(bytes)];
Change CFSwapInt16HostToBig to CFSwapInt16HostToLitte if appropriate.
According to my requirement:
The input string has to be converted into Byte Values.
Each character of string , which are 16 bit values , has to be converted to low 8 bits.
The Sha1 is then computed over the byte Array.
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.
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];
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];
}
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.
Here's an NSString category for creating a SHA1 hash of an NSString.
Creating SHA1 Hash from NSString