【问题标题】:How can i convert NSdata to hex string?如何将 NSdata 转换为十六进制字符串?
【发布时间】:2013-05-07 10:25:44
【问题描述】:

我尝试了以下代码将 NSData 转换为十六进制字符串值,但都错了?

这里的“结果”是我的 NSdata

我需要一个十六进制字符串作为输出,但我没有得到它

NSUInteger dataLength = [result length];
  NSLog(@"%d",dataLength);
    NSMutableString *string = [NSMutableString stringWithCapacity:dataLength*2];
   const unsigned char *dataBytes = [result bytes];
    for (NSInteger idx = 0; idx < dataLength; ++idx) {        [string appendFormat:@"%02x", dataBytes[idx]];
 }    
    NSLog(@"%@",string);

请问如何转换

更新:结果数据包含加密字符串。我想将其转换为十六进制值

【问题讨论】:

标签: ios objective-c nsstring hex


【解决方案1】:

这个答案是在 Xcode 10 Playground 中运行的 Swift 4.2 中。

import Foundation

let d = Data(bytes: [0x3f, 0x09, 0x0a, 0xa3, 0x01])
let s:String = d.compactMap({ String(format: "%02x ", $0) }).joined()
print(s)

这是输出:

3f 09 0a a3 01 

【讨论】:

    【解决方案2】:

    这是整数运算的转换:

    -(NSString*)hex:(NSData*)data{
         NSMutableData *result = [NSMutableData dataWithLength:2*data.length];
         unsigned const char* src = data.bytes;
         unsigned char* dst = result.mutableBytes;
         unsigned char t0, t1;
    
         for (int i = 0; i < data.length; i ++ ) {
              t0 = src[i] >> 4;
              t1 = src[i] & 0x0F;
    
              dst[i*2] = 48 + t0 + (t0 / 10) * 39;
              dst[i*2+1] = 48 + t1 + (t1 / 10) * 39;
         }
    
         return [[NSString alloc] initWithData:result encoding:NSASCIIStringEncoding];
    }
    

    【讨论】:

    • 好吧,我终于知道39'a' - '0' - 10
    【解决方案3】:

    Swift 2 version

    private let kHexChars = Array("0123456789abcdef".utf8) as [UInt8];
    
    extension NSData {
    
        public func hexString() -> String {
            guard length > 0 else {
                return ""
            }
    
            let buffer = UnsafeBufferPointer<UInt8>(start: UnsafePointer(bytes), count: length)
            var output = [UInt8](count: length*2 + 1, repeatedValue: 0)
            var i: Int = 0
            for b in buffer {
                let h = Int((b & 0xf0) >> 4)
                let l = Int(b & 0x0f)
                output[i++] = kHexChars[h]
                output[i++] = kHexChars[l]
            }
    
            return String.fromCString(UnsafePointer(output))!
        }
    }
    

    【讨论】:

      【解决方案4】:

      这是我为此而设的一个类别。这只是为您提供十六进制数据的所有字符。没有换行或任何东西。

      @implementation NSData (NSData_Conversion)
      
      #pragma mark - String Conversion
      - (NSString *)hexadecimalString
      {
          /* Returns hexadecimal string of NSData. Empty string if data is empty.   */
      
          const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
      
          if (!dataBuffer)
          {
              return [NSString string];
          }
      
          NSUInteger          dataLength  = [self length];
          NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
      
          for (int i = 0; i < dataLength; ++i)
          {
              [hexString appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
          }
      
          return [NSString stringWithString:hexString];
      }
      

      【讨论】:

        【解决方案5】:

        最简单的解决方案是遍历 NSData 的字节并从中构造 NSString。使用 [yourData bytes] 访问字节,并将字符串构建为 NSMutableString。

        这是一个使用 NSData 类别实现的示例

        interface NSData(Hex)
        -(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces;
        @end
        
        @implementation NSData(Hex)
        -(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces
        {
            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; ) {
                [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 autorelease];
        }
        @end
        
        
        
        
        
          NSData* data = ...
        NSString* hex = [data hexRepresentationWithSpaces_AS:YES];
        

        【讨论】:

          猜你喜欢
          • 2011-11-23
          • 2013-12-01
          • 2014-12-17
          • 2012-01-06
          • 2013-02-07
          • 2017-08-23
          • 2014-03-19
          相关资源
          最近更新 更多