6

Incase of android everything is working perfectly. I want to implement same feature in iOS too but getting different values. Please check the description with images below.

In Java/Android Case:

I tried to convert the string to base64 byte array in java like

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

Output: enter image description here

In Swift3/iOS Case:

I tried to convert the string to base64 byte array in swift like

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

Output: enter image description here

jazzbpn
  • 6,441
  • 16
  • 63
  • 99
  • 1
    Different values? `-55` vs `201` seems almost "equals", no? I mean in iOS, it's `UInt8` (it's seen in your screenshot), and in Java I guess it's `Int8`, meaning unsigned vs signed (so 0 to 255 and -127 to 128). – Larme Dec 18 '17 at 09:47
  • 1
    Thank you so much for the answer @Larme – jazzbpn Dec 18 '17 at 10:50
  • 1
    @Larme,I want to know one more thing. How to convert Int8/UInt8 byte array to readable string format ? Here using this way I try to convert to string. But it prints not a valid UTF-8 sequence. if let string = String(data: data, encoding: .utf8) { print(string) } else { print("not a valid UTF-8 sequence") } – jazzbpn Dec 19 '17 at 04:48
  • 1
    https://stackoverflow.com/questions/39075043/how-to-convert-data-to-hex-string-in-swift or if you want the "int" instead of the "hex" use a different format https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1 – Larme Dec 19 '17 at 06:16

2 Answers2

6

Finally solved:

This is due to signed and unsigned integer, meaning unsigned vs signed (so 0 to 255 and -127 to 128). Here, we need to convert the UInt8 array to Int8 array and therefore the problem will be solved.

let intArray = data1.map { Int8(bitPattern: $0) }
jazzbpn
  • 6,441
  • 16
  • 63
  • 99
0

In no case should you try to compare data on 2 systems the way you just did. That goes for all types but specially for raw data.

Raw data are NOT presentable without additional context which means any system that does present them may choose how to present them (raw data may represent some text in UTF8 or some ASCII, maybe jpeg image or png or raw RGB pixel data, it might be an audio sample or whatever). In your case one system is showing them as a list of signed 8bit integers while the other uses 8bit unsigned integers for the same thing. Another system might for instance show you a hex string which would look completely different.

As @Larme already mentioned these look the same as it is safe to assume that one system uses signed and the other unsigned values. So to convert from signed (Android) to unsigned (iOS) you need to convert negative values as unsigned = 256+signet so for instance -55 => 256 + (-55) = 201.

If you really need to compare data in your case it is the best to save them into some file as raw data. Then transfer that file to another system and compare native raw data to those in file to check there is really a difference.

EDIT (from comment):

Printing raw data as a string is a problem but there are a few ways. The thing is that many bytes are not printable as strings, may be whitespaces or some reserved codes but mostly the problem is that value of 0 means the end of string in most cases which may exist in the middle of your byte sequence.

So you already have 2 ways of printing byte by byte which is showing Int8 or Uint8 corresponding values. As described in comment converting directly to string may not work as easy as

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

One way of converting data to string may be to convert each byte into a corresponding character. Check this code:

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

Then to test it I used:

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)

The printing result is:

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

Then another popular way is using a hex string. It can be displayed as:

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

And with the same data as before the result is:

000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff

I hope this is enough but in general you could do pretty much anything with array of bytes and show them. For instance you could create an image treating bytes as RGB 8-bit per component if it would make sense. It might sound silly but if you are looking for some patterns it might be quite a witty solution.

Matic Oblak
  • 16,318
  • 3
  • 24
  • 43
  • Matic thank you so much for the answer, I want to know one more thing. How to convert Int8/UInt8 byte array to readable string format ? Here using this way I try to convert to string. But it prints not a valid UTF-8 sequence. if let string = String(data: data, encoding: .utf8) { print(string) } else { print("not a valid UTF-8 sequence") } – jazzbpn Dec 19 '17 at 04:27
  • @jazzbpn Please check my edit and let me know if this explains is. – Matic Oblak Dec 19 '17 at 08:05