2017-12-18 401 views
0

Incase of android一切正常。我想在iOS中實現相同的功能,但獲得不同的值。請用下面的圖片檢查描述。在swift和java中將字符串轉換爲base64字節數組賦予不同的值

在Java/Android的案例:

我試圖將字符串轉換爲base64字節數組中的java

byte[] data1 = Base64.decode(balance, Base64.DEFAULT); 

輸出: enter image description here

在Swift3/iOS案例:

我試圖將字符串轉換爲base64字節數組中迅速

let data:Data = Data(base64Encoded: balance, options: NSData.Base64DecodingOptions(rawValue: 0))! 
let data1:Array = (data.bytes) 

輸出: enter image description here

+0

不同的值? '-55' vs'201'似乎幾乎「等於」,不是嗎?我的意思是在iOS中,它是'UInt8'(它在你的屏幕截圖中看到),而在Java中,我猜它是'Int8',意思是無符號與帶符號(所以0到255和-127到128)。 – Larme

+0

非常感謝你的回答@Larme – jazzbpn

+0

@ Larme,我想知道一件事。如何將Int8/UInt8字節數組轉換爲可讀的字符串格式?在這裏使用這種方式我嘗試轉換爲字符串。但它不打印有效的UTF-8序列。如果讓string = String(data:data,encoding:.utf8){print(string)} else {print(「不是有效的UTF-8序列」)} – jazzbpn

回答

0

終於解決:

這是由於簽署和無符號整數,意味着無符號與有符號(所以0到255和-127到128)。這裏,我們需要將UInt8數組轉換爲Int8數組,因此問題就解決了。

let intArray = data1.map { Int8(bitPattern: $0) } 
0

在任何情況下,你應該嘗試將數據在2個系統中,你只是做的方式進行比較。這適用於所有類型,但特別適用於原始數據。

如果沒有附加的上下文,原始數據不會呈現,這意味着任何呈現它們的系統可能會選擇如何呈現它們(原始數據可能代表一些UTF8或某些ASCII文本,可能是jpeg圖像或png或原始RGB像素數據,它可能是一個音頻樣本或其他)。在你的情況下,一個系統將它們顯示爲已簽名8位整數列表,而另一個系統使用8位無符號整數表示同一事物。另一個系統可能會顯示一個看起來完全不同的十六進制字符串。

正如@Larme已經提到的,這些看起來是一樣的,因爲假定一個系統使用帶符號和其他無符號值是安全的。因此,要將已簽名(Android)轉換爲未簽名(iOS),您需要將負值轉換爲unsigned = 256+signet,例如-55 => 256 + (-55) = 201

如果您確實需要比較您的案例中的數據,最好將它們作爲原始數據保存到某個文件中。然後將該文件傳輸到另一個系統,並將本機原始數據與文件中的數據進行比較,以檢查是否存在差異。

編輯(從評論):

打印原始數據作爲一個字符串是一個問題,但有幾個方法。問題在於許多字節不能作爲字符串打印,可能是空格或一些保留的代碼,但大多數問題是值爲0意味着在大多數情況下字符串的結尾可能存在於字節序列的中間。

因此,您已經有2種逐字節打印的方式,它顯示Int8Uint8相應的值。如在註釋中所描述直接轉換爲字符串可能不工作容易,因爲

let string = String(data: data, encoding: .utf8) // Will return nil for strange strings 

一個數據轉換爲字符串可以是每個字節轉換爲對應的字符的方式。檢查驗證碼:

let characterSequence = data.map { UnicodeScalar($0) } // Create an array of characters from bytes 
let stringArray = characterSequence.map { String($0) } // Create an array of strings from array of characters 
let myString = stringArray.reduce("", { $0 + $1 }) // Convert an array of strings to a single string 

let myString2 = data.reduce("", { $0 + String(UnicodeScalar($1)) }) // Same thing in a single line 

然後對其進行測試我使用:

let data = Data(bytes: Array(0...255)) // Generates with byte values of 0, 1, 2... up to 255 
let myString2 = data.reduce("", { $0 + String(UnicodeScalar($1)) }) 
print(myString2) 

打印結果是:

!"#$%&'()*+,-./:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ 

然後另一種流行的方法是使用一個十六進制字符串。它可以顯示爲:

let hexString = data.reduce("", { $0 + String(format: "%02hhx",$1) }) 
print(hexString) 

而且具有相同的數據結果之前是:

000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 

我希望這是足夠的,但總的來說,你可以做的字節數組和相當多的東西給他們看。例如,如果它有意義,您可以創建一個圖像處理字節爲每個組件8位RGB。這可能聽起來很愚蠢,但如果你正在尋找一些模式,這可能是一個非常機智的解決方案。

+0

馬蒂奇非常感謝你的回答,我想知道更多的事情。如何將Int8/UInt8字節數組轉換爲可讀的字符串格式?在這裏使用這種方式我嘗試轉換爲字符串。但它不打印有效的UTF-8序列。 如果讓字符串=字符串(數據:數據,編碼:.utf8){ 打印(串) }其他{ 打印( 「不是一個合法的UTF-8序列」) } – jazzbpn

+0

@jazzbpn請檢查我的編輯,讓我知道這是否解釋是。 –

相關問題