2012-11-21 22 views
5

Convert NSData into HEX NSSString轉換NSData的成十六進制的NSString參照以下問題

我已經解決了這是由埃裏克Aigner的提供了一種使用所述溶液中的問題:

NSData *data = ...; 
NSUInteger capacity = [data length] * 2; 
NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:capacity]; 
const unsigned char *dataBuffer = [data bytes]; 
NSInteger i; 
for (i=0; i<[data length]; ++i) { 
    [stringBuffer appendFormat:@"%02X", (NSUInteger)dataBuffer[i]]; 
} 

然而,存在一個小問題如果後面有額外的零,字符串值將會不同。例如。如果六數據是字符串@「37000000億」,當使用掃描儀到整數轉換的:

unsigned result = 0; 
NSScanner *scanner = [NSScanner scannerWithString:stringBuffer]; 
[scanner scanHexInt:&result]; 
NSLog(@"INTEGER: %u",result); 

其結果將是4294967295,這是不正確。它不應該是55,因爲只有六十七採取?

那麼我該如何擺脫零?

編輯:(針對CRD)

您好,感謝澄清我的疑慮。那麼你在做什麼是直接從字節指針直接讀取64位整數?不過,我還有一個問題。你如何實際將NSData轉換爲字節指針?

爲了讓你更容易理解,我會解釋我最初做了什麼。

首先,我所做的就是要顯示的我的文件的數據(數據是十六進制)

NSData *file = [NSData dataWithContentsOfFile:@"file path here"]; 
NSLog(@"Patch File: %@",file); 

輸出:

enter image description here

接着,我所做的就是讀取並抵消文件的前8個字節並將它們轉換爲字符串。

// 0-8 bytes 
[file seekToFileOffset:0]; 
NSData *b = [file readDataOfLength:8]; 
NSUInteger capacity = [b length] * 2; 
NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:capacity]; 
const unsigned char *dataBuffer = [b bytes]; 
NSInteger i; 
for (i=0; i<[b length]; ++i) { 
    [stringBuffer appendFormat:@"%02X", (NSUInteger)dataBuffer[i]]; 
} 
NSLog(@"0-8 bytes HEXADECIMAL: %@",stringBuffer); 

正如你所看到的,0x3700000000000000是下一個8個字節。爲了訪問接下來的8個字節,我必須做的唯一改變是將SeekFileToOffset的值改爲8,以便訪問接下來的8個字節的數據。

總而言之,您給我的解決方案很有用,但手動輸入十六進制值並不實際。如果將字節格式化爲字符串然後解析它們不是實現它的方法,那麼我如何直接訪問數據的前8個字節並將它們轉換爲字節指針?

+0

這是一個非常緩慢的實施。首先格式化成緩衝區,然後轉換爲'NSString'。 – trojanfoe

回答

3

您似乎試圖將存儲在NSData轉換爲64位整數(0x3700000000000000中有8個字節)。

如果這是你的目標,那麼通過將字節格式化爲一個字符串然後解析它們的方式是而不是這樣做。你需要知道你的數據是什麼格式(即最低或最高有效字節在先),然後使用適當的端序轉換函數。

順便說一句,你得到4294967295(0xFFFFFFFF)的原因是因爲你要求NSScanner讀取32位整數並且你的編號(0x3700000000000000)溢出。

迴應置評

由於86是小端,你可以通過只鑄造讀little-endian的64位整數一個字節的指針直接:

Byte bytes[] = { 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
NSLog(@"%lld", *(int64_t *)bytes); 

如果您需要閱讀big-endian數據,然後你可以使用endian轉換功能,如Endian64_Swap - 它只是翻轉你有什麼,所以閱讀然後翻轉。

請注意,x86不會要求要求數據訪問被對齊,但如果是的話會表現更好。

+0

這是我想要實現的。我以前嘗試使用帶NSUTF16LittleEndianStringEncoding的NSData來初始化字符串,但它給了我7個。但是,在閱讀你的答案並從外部尋求建議之後,我意識到這樣做是有缺陷的,並且完全錯誤。任何想法如何找出我的數據在轉換之前是什麼endian格式? – Dawson

+0

@Dawson - 有一種真正確定endian格式的方法,你可以根據這些值來猜測,但是你不會真的知道*。所以除非你知道值的期望範圍,否則你需要從誰來生產數據中找到答案。 – CRD

+0

假設數據是小尾數格式。我可以使用什麼合適的轉換函數將(0x3700000000000000)轉換爲64位整數,在本例中爲55?據我所知,NSScanner似乎沒有適當的功能。 – Dawson

3

4,294,967,295是ULONG_MAX,所以看起來掃描儀只是溢出。 (scanHexInt方法吃所有它找到的六位數,並且因爲零也是一個六位數字,方法slurps整個數字,越過ULONG_MAX。)

+0

這個問題似乎與最重要和最不重要的位。如果我使用小端編碼,字符串很可能只需要37個字符,並忽略後面的零。但是,我怎麼做到這一點? – Dawson

+0

從高層次看,你真的想做什麼? – zoul

+0

我試圖將8個字節轉換爲64位整數,但我不知道什麼是適當的方式來做到這一點。這似乎是我的方法來實現這是錯誤的。因此,我正在尋求一些建議。 – Dawson