通过将NSString解释为十六进制数字来创建NSData

时间:2012-08-08 03:05:30

标签: ios cocoa nsstring nsdata

EDIT1: rob mayoff'answer很精彩。这是我自己的:

    -(NSData *)change:(NSString *)hexString
    {
        int j=0;
        Byte bytes[[hexString length]];  
        for(int i=0;i<[hexString length];i++)
        {
            int int_ch;  

        unichar hex_char1 = [hexString characterAtIndex:i]; 
        int int_ch1;
        if(hex_char1 >= '0' && hex_char1 <='9')
            int_ch1 = (hex_char1-48)*16;   
        else if(hex_char1 >= 'A' && hex_char1 <='F')
            int_ch1 = (hex_char1-55)*16; 
        else 
            int_ch1 = (hex_char1-87)*16; 
        i++;

        unichar hex_char2 = [hexString characterAtIndex:i]; 
        int int_ch2;
        if(hex_char2 >= '0' && hex_char2 <='9')
            int_ch2 = (hex_char2-48); 
        else if(hex_char1 >= 'A' && hex_char1 <='F')
            int_ch2 = hex_char2-55; 
        else 
            int_ch2 = hex_char2-87; 

        int_ch = int_ch1+int_ch2;

        bytes[j] = int_ch;
        j++;
    }
    NSData *newData = [[NSData alloc] initWithBytes:bytes length:[hexString length]/2];
    return newData;
}

-------编辑单独-------------------------------------- ----------

我有一个十六进制数字的NSString,如下所示:

NSString *aString =@“8dfe2f9a9384573fa0ffae17c3bef4cc2ba056cc5cbbfab57ac78c83af4ef8a48ea1728d904e87613845377821e01e07cc6c9dea35516dc595421e0ffc7caa7a19671e713bb74d84d1dd4fb2c972dd8facf5d74ad32662e992ea13d2417abcaee4137098322394ba76badbaf4c1db344704bbf9ed8a1513ff4b2e766526c98a2808b7ae67d1866cb9b489764e70662b1499d8d467a8817d1304aab8f92ebddd3e871cc1374cae96a1428f0c2afcb3f43e705cdd7649bde5a363d59125980d0acbbe32879b96ab15e93f74c08d435b787a8ee734e2773e16ae8f4cb4a5ddad989f92cf1c609f0f8b81fedb67f974ae583548b13c86b6fe1925a33a47cbda8ed54c20f2d8020650ba7fabbf8cbac00493b6de423880ef1a1af8cddc457c064cd6150aa30d34456e422ea707c313c7fbb428ce1c4e534ea8edd8c21b62d526522606e6944c4058e631dafc6f9a539f9a4dfd8afeccef51a8a4904a3efa0a76f3ca55ab56c726b0787d9ebb261ca91f5abbf985096b327a6269399ac11a23cafb0b3a6b3fb4aa357fc1644c89b7dee396c51af734738e598b765b2384eb8931f4b65d9f4b6c73ee3f1f6c5aa17871d14335153e4058ab9bc0fcad35dbdb924d00b0a71b985e20cdf530fa5479e2dd8f14d269ce59da365bac03fccb037963e7e3f175a09dd7efc66e450df5a16e7233ea55009e4891ef238d003d5837f077c12167428ad19d3da45d569aa252d5ffd736e134ad3b5654fd82506822be9b78731c9ca5ee56685153e657e8b385013ff14bbe5a1f5938801e94fe498495c2d94c84a937e1c36a4667a16dfeced471c3902b4b3d1daa9f2c72a09af736ef51ebe39f0006667d60ddc9ec20c5c29cc8933e5fb9e293560db6b1s2df4864bd9cf02b0d40d5b24d0326f1d7e251a0cbc692b68fa37212a57f34588d18d6f4f7e59d997a8c4b5e452fe883645b90bd7ee3a4b38754616ca7a9d430620036dbead2ec03bebb5c69e92f9a33951c22e83e68dd85350c7”

我希望将其更改为NSData,如下所示:

NSData *aData = <8dfe2f9a 9384573f a0ffae17 c3bef4cc 2ba056cc 5cbbfab5 7ac78c83 af4ef8a4 8ea1728d 904e8761 38453778 21e01e07 cc6c9dea 35516dc5 95421e0f fc7caa7a 19671e71 3bb74d84 d1dd4fb2 c972dd8f acf5d74a d32662e9 92ea13d2 417abcae e4137098 322394ba 76badbaf 4c1db344 704bbf9e d8a1513f f4b2e766 526c98a2 808b7ae6 7d1866cb 9b489764 e70662b1 499d8d46 7a8817d1 304aab8f 92ebddd3 e871cc13 74cae96a 1428f0c2 afcb3f43 e705cdd7 649bde5a 363d5912 5980d0ac bbe32879 b96ab15e 93f74c08 d435b787 a8ee734e 2773e16a e8f4cb4a 5ddad989 f92cf1c6 09f0f8b8 1fedb67f 974ae583 548b13c8 6b6fe192 5a33a47c bda8ed54 c20f2d80 20650ba7 fabbf8cb ac00493b 6de42388 0ef1a1af 8cddc457 c064cd61 50aa30d3 4456e422 ea707c31 3c7fbb42 8ce1c4e5 34ea8edd 8c21b62d 52652260 6e6944c4 058e631d afc6f9a5 39f9a4df d8afecce f51a8a49 04a3efa0 a76f3ca5 5ab56c72 6b0787d9 ebb261ca 91f5abbf 985096b3 27a62693 99ac11a2 3cafb0b3 a6b3fb4a a357fc16 44c89b7d ee396c51 af734738 e598b765 b2384eb8 931f4b65 d9f4b6c7 3ee3f1f6 c5aa1787 1d143351 53e4058a b9bc0fca d35dbdb9 24d00b0a 71b985e2 0cdf530f a5479e2d d8f14d26 9ce59da3 65bac03f ccb03796 3e7e3f17 5a09dd7e fc66e450 df5a16e7 233ea550 09e4891e f238d003 d5837f07 7c121674 28ad19d3 da45d569 aa252d5f fd736e13 4ad3b565 4fd82506 822be9b7 8731c9ca 5ee56685 153e657e 8b385013 ff14bbe5 a1f59388 01e94fe4 98495c2d 94c84a93 7e1c36a4 667a16df eced471c 3902b4b3 d1daa9f2 c72a09af 736ef51e be39f000 6667d60d dc9ec20c 5c29cc89 33e5fb9e 293560db 6b152df4 864bd9cf 02b0d40d 5b24d032 6f1d7e25 1a0cbc69 2b68fa37 212a57f3 4588d18d 6f4f7e59 d997a8c4 b5e452fe 883645b9 0bd7ee3a 4b387546 16ca7a9d 43062003 6dbead2e c03bebb5 c69e92f9 a33951c2 2e83e68d d85350c7>

有人能告诉我怎么做吗?

3 个答案:

答案 0 :(得分:6)

我猜你所说的是你有一个NSString,你想把字符串中的字符解释为十六进制数字,并创建一个NSData,其内容是那些字节所代表的字节十六进制数字。我已经编辑了你的问题。

有很多方法可以做到这一点。这是一个完全没有优化的,不能优雅地处理错误的。但我确实在你的例子上测试了它。

NSData *dataByIntepretingHexString(NSString *hexString) {
    char const *chars = hexString.UTF8String;
    NSUInteger charCount = strlen(chars);
    if (charCount % 2 != 0) {
        return nil;
    }
    NSUInteger byteCount = charCount / 2;
    uint8_t *bytes = malloc(byteCount);
    for (int i = 0; i < byteCount; ++i) {
        unsigned int value;
        sscanf(chars + i * 2, "%2x", &value);
        bytes[i] = value;
    }
    return [NSData dataWithBytesNoCopy:bytes length:byteCount freeWhenDone:YES];
}

答案 1 :(得分:0)

-(NSMutableData*)hexDataFromString:(NSString*)string{

    NSMutableData *hexData= [[NSMutableData alloc] init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [string length]/2; i++) {
        byte_chars[0] = [string characterAtIndex:i*2];
        byte_chars[1] = [string characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [hexData appendBytes:&whole_byte length:1];
    }
    return hexData;
}

答案 2 :(得分:0)

接受的答案,同时充分展示了这个想法。由于sscanf可能会遇到性能问题。另一个答案可能应该被赞成。以下可能是帮助,但不检查格式错误的数据。

+(uint8_t)hexCharacterValue:(unichar)hexChar{
    if(hexChar > 0x60) return (hexChar - 0x57);
    if(hexChar > 0x40) return (hexChar - 0x37);
    return (hexChar - 0x30);
}

+(NSData*)dataWithOctetString:(NSString*)string{
    NSUInteger byteCount = [string length]/2;
    uint8_t* bytes = (uint8_t*) malloc(byteCount*sizeof(uint8_t));
    for(NSUInteger j = 0, i=0; j<[string length]; j+=2,i++) bytes[i] = ([[self class] hexValue:[string characterAtIndex:j]] << 4) | [[self class] hexValue:[string characterAtIndex:j+1]];
    return [NSData dataWithBytesNoCopy:bytes length:byteCount freeWhenDone:YES];
}