【问题标题】:How to convert an NSString to hex values如何将 NSString 转换为十六进制值
【发布时间】:2011-03-04 15:51:09
【问题描述】:

我想将常规 NSString 转换为带有(我假设是)ASCII 十六进制值并返回的 NSString。

我需要产生与下面的 Java 方法相同的输出,但我似乎无法在 Objective-C 中找到一种方法。我在 C 和 C++ 中找到了一些示例,但我很难将它们应用到我的代码中。

这是我试图重现的 Java 方法:

/**
* Encodes the given string by using the hexadecimal representation of its UTF-8 bytes.
*
* @param s The string to encode.
* @return The encoded string.
*/
public static String utf8HexEncode(String s) {
    if (s == null) {
        return null;
    }
    byte[] utf8;
    try {
        utf8 = s.getBytes(ENCODING_UTF8);
    } catch (UnsupportedEncodingException x) {
        throw new RuntimeException(x);
    }
    return String.valueOf(Hex.encodeHex(utf8));
}

/**
* Decodes the given string by using the hexadecimal representation of its UTF-8 bytes.
*
* @param s The string to decode.
* @return The decoded string.
* @throws Exception If an error occurs.
*/
public static String utf8HexDecode(String s) throws Exception {
if (s == null) {
    return null;
}
    return new String(Hex.decodeHex(s.toCharArray()), ENCODING_UTF8);
} 

更新:感谢drawonward的回答,这是我为创建十六进制NSStrings而编写的方法。它在 char 声明行上给了我一个“初始化丢弃来自指针目标类型的限定符”警告,但它有效。

- (NSString *)stringToHex:(NSString *)string
{
    char *utf8 = [string UTF8String];
    NSMutableString *hex = [NSMutableString string];
    while ( *utf8 ) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];

    return [NSString stringWithFormat:@"%@", hex];
}

还没来得及写解码方法。当我这样做时,我将对其进行编辑以将其发布给其他感兴趣的人。

Update2: 所以我上面发布的方法实际上并没有输出我正在寻找的东西。它不是以 0-f 格式输出十六进制值,而是输出所有数字。我终于重新开始解决这个问题,并且能够为 NSString 编写一个与我发布的 Java 方法完全相同的类别。这里是:

//
//  NSString+hex.h
//  Created by Ben Baron on 10/20/10.
//

@interface NSString (hex) 

    + (NSString *) stringFromHex:(NSString *)str;
    + (NSString *) stringToHex:(NSString *)str;

@end

//
//  NSString+hex.m
//  Created by Ben Baron on 10/20/10.
//

#import "NSString+hex.h"

@implementation NSString (hex)

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

    return [[[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding] autorelease];
}

+ (NSString *) stringToHex:(NSString *)str
{   
    NSUInteger len = [str length];
    unichar *chars = malloc(len * sizeof(unichar));
    [str getCharacters:chars];

    NSMutableString *hexString = [[NSMutableString alloc] init];

    for(NSUInteger i = 0; i < len; i++ )
    {
        [hexString appendString:[NSString stringWithFormat:@"%x", chars[i]]];
    }
    free(chars);

    return [hexString autorelease];
}

@end

【问题讨论】:

  • 我家里有这个代码。下班后我会发布它,除非有人打败我。
  • 嗨,我知道这是一篇旧帖子。但是我遇到了您遇到的问题,是的。您对stringFromHex 方法的发现也是我一直在寻找的。我可以知道您从哪里获得该方法,并且有关于它的教程吗?我想了解那个方法,我自己无法分析。谢谢。
  • 对不起,时间太长了,我不记得了。
  • 方法 stringToHex: 仍然只输出数字 :(

标签: iphone objective-c


【解决方案1】:

我的输入是一个数字 base10 字符串,输出应该是字符串格式的十六进制表示。例子:

  • @"10" -> @"A"
  • @"1128" -> @"468"
  • @"1833828235" -> @"6D4DFF8B"

实施:

+ (NSString *) stringToHex:(NSString *)str{
NSInteger result = [str integerValue];
NSString *hexStr = (result)?@"":@"0";

while (result!=0) {
     NSInteger reminder = result % 16;

    if(reminder>=0 && reminder<=9){
        hexStr = [[NSString stringWithFormat:@"%ld",(long)reminder] stringByAppendingString:hexStr];
    }else if(reminder==10){
        hexStr = [@"A" stringByAppendingString:hexStr];
    }else if(reminder==11){
        hexStr = [@"B" stringByAppendingString:hexStr];
    }else if(reminder==12){
        hexStr = [@"C" stringByAppendingString:hexStr];
    }else if(reminder==13){
        hexStr = [@"D" stringByAppendingString:hexStr];
    }else if(reminder==14){
        hexStr = [@"E" stringByAppendingString:hexStr];
    }else{
        hexStr = [@"F" stringByAppendingString:hexStr];
    }

    result /=16;
}

return hexStr;

}

【讨论】:

    【解决方案2】:

    将 nsstring 转换为十六进制值的完美快捷方式

    NSMutableString *tempHex=[[NSMutableString alloc] init];
    
    [tempHex appendString:@"0xD2D2D2"];
    
    unsigned colorInt = 0;
    
    [[NSScanner scannerWithString:tempHex] scanHexInt:&colorInt];
    
    lblAttString.backgroundColor=UIColorFromRGB(colorInt);
    

    这段代码使用的宏是----

    #define UIColorFromRGB(rgbValue) 
    [UIColor \colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
    green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
    blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
    

    【讨论】:

    • 也许将您的 UIColorFromRGB 宏实现与您的答案一起添加。
    • 嗨@JasperBlues 我已经用所需的宏更新了我的帖子。
    【解决方案3】:

    一种可能的解决方案:

    +(NSString*)hexFromStr:(NSString*)str
    {
        NSData* nsData = [str dataUsingEncoding:NSUTF8StringEncoding];
        const char* data = [nsData bytes];
        NSUInteger len = nsData.length;
        NSMutableString* hex = [NSMutableString string];
        for(int i = 0; i < len; ++i)[hex appendFormat:@"%02X", data[i]];
        return hex;
    }
    

    【讨论】:

    • const 在这里不合适。
    【解决方案4】:

    感谢所有为本主题做出贡献的人。这对我帮助很大。由于自原始帖子以来事情发生了一些变化,这是我为 iOS 6 更新的实现。我采用了类别方法,但选择在 NSData 和 NSString 之间分配负载。欢迎评论。

    首先是 NSString 的一半,它将十六进制编码的字符串解码为 NSData 对象。

    @implementation NSString (StringToHexData)
    
    //
    // Decodes an NSString containing hex encoded bytes into an NSData object
    //
    - (NSData *) stringToHexData
    {
        int len = [self length] / 2;    // Target length
        unsigned char *buf = malloc(len)
        unsigned char *whole_byte = buf;
        char byte_chars[3] = {'\0','\0','\0'};
    
        int i;
        for (i=0; i < [self length] / 2; i++) {
            byte_chars[0] = [self characterAtIndex:i*2];
            byte_chars[1] = [self characterAtIndex:i*2+1];
            *whole_byte = strtol(byte_chars, NULL, 16);
            whole_byte++;
        }
    
        NSData *data = [NSData dataWithBytes:buf length:len];
        free( buf );
        return data;
    }
    @end
    

    这些更改主要是为了提高效率:一些简单的老式指针算法意味着我可以一次性分配整个缓冲区,并逐字节填充它。然后将整个事情一次性传递给NSData。

    NSData 中的编码部分如下所示:

    @implementation NSData (DataToHexString)
    
    - (NSString *) dataToHexString
    {
        NSUInteger          len = [self length];
        char *              chars = (char *)[self bytes];
        NSMutableString *   hexString = [[NSMutableString alloc] init];
    
        for(NSUInteger i = 0; i < len; i++ )
            [hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]];
    
        return hexString;
    }
    @end
    

    再次,一些小的变化,虽然我怀疑这里没有效率提升。使用 "%0.2hhx" 解决了所有丢失前导零的问题,并确保一次只输出一个字节。

    希望这有助于下一个人接受这个!

    【讨论】:

      【解决方案5】:

      对于这些 Java 行

      utf8 = s.getBytes(ENCODING_UTF8);
      new String(decodedHexString, ENCODING_UTF8);
      

      Objective-C 等效项是

      utf8 = [s UTF8String];
      [NSString initWithUTF8String:decodedHexString];
      

      用字符串的十六进制表示创建一个 NSString:

      NSMutableString *hex = [NSMutableString string];
      while ( *utf8 ) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];
      

      您必须创建自己的 decodeHex 函数。只需从字符串中提取两个字符,如果它们有效,则在结果中添加一个字节。

      【讨论】:

      • 应该是“NSMutableString *hex = [NSMutableString string];”
      • 我喜欢while loop 一个班轮的这个答案。小心使用 NULL 字节。如果您尝试abc。然后检查结果:csrc.nist.gov/CSRC/media/Projects/… 此代码在十六进制编码哈希末尾的 NULL 字节上阻塞..
      【解决方案6】:

      您的 stringToHex 方法存在问题 - 它会丢弃前导 0,并忽略 00。作为一个快速修复,我做了以下:

      + (NSString *) stringToHex:(NSString *)str
      {   
          NSUInteger len = [str length];
          unichar *chars = malloc(len * sizeof(unichar));
          [str getCharacters:chars];
      
          NSMutableString *hexString = [[NSMutableString alloc] init];
      
          for(NSUInteger i = 0; i < len; i++ )
          {
              // [hexString [NSString stringWithFormat:@"%02x", chars[i]]]; /*previous input*/
              [hexString appendFormat:@"%02x", chars[i]]; /*EDITED PER COMMENT BELOW*/
          }
          free(chars);
      
          return [hexString autorelease];
      }
      

      【讨论】:

      • 我没有意识到这一点。可能会导致我不知道存在的随机罕见错误。谢谢!
      • 顺便说一句,您的代码中有一个小错误,[hexString [NSString stringWithFormat:@"%02x", chars[i]]]; 应该是 [hexString appendString:[NSString stringWithFormat:@"%02x", chars[i]]]; 或者更好的 [hexString appendFormat:@"%02x", chars[i]];
      • 我还没有编辑权限,所以我无法通过修复编辑您的答案。
      【解决方案7】:

      首先,我要感谢drawnonward 的回答。这给了我第一个功能,既简单又干净。本着同样的精神,我写了另一篇。希望你喜欢。

      @synthesize unsigned char* value= _value;
      
      - (NSString*) hexString
      {
          _value[CONSTANT]= '\0';
          unsigned char* ptr= _value;
      
          NSMutableString* hex = [[NSMutableString alloc] init];
          while ( *ptr ) [hex appendFormat:@"%02x", *ptr++ & 0x00FF];
      
          return [hex autorelease];
      }
      
      - (void) setHexString:(NSString*)hexString
      {
          _value[CONSTANT]= '\0';
          unsigned char* ptr= _value;
      
          for (const char* src= [hexString cStringUsingEncoding:NSASCIIStringEncoding];
               *src;
               src+=2)
          {
              unsigned int hexByte;
              /*int res=*/ sscanf(src,"%02x",&hexByte);
              *ptr++= (unsigned char)(hexByte & 0x00FF);
          }
          *ptr= '\0';
      }
      

      【讨论】:

        【解决方案8】:

        也许您应该使用NSString dataUsingEncoding: 进行编码和initWithData:length:encoding: 进行解码。取决于您从哪里获取数据。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-16
          • 2011-05-15
          • 2017-04-03
          • 2011-09-04
          • 2012-10-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多