Reputation: 31
I made a test code for toByteArray()
.
The abc
variable receives a String "567"
and converts it to ByteArray
and outputs it, which is always written as follows.
I/System.out: abc = 567
I/System.out: [B@fde8d29
However, when I input "567"
as a String in EditText
and convert it to ByteArray
, the values are always written differently as shown below.
I/System.out: def = 567
[B@44e82b
I/System.out: def = 567
[B@b6d0134
I/System.out: def = 567
[B@cae8059
I/System.out: def = 567
[B@251342a
I/System.out: def = 567
[B@e19d4f7
I'm implementing a socket program, and I need to get a String in EditText
and send it to the byte sequence, but the value always changes.
How can I solve this problem?
package com.cfsuman.myapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var abc = "567"
println("abc = ${abc}")
var test1= abc.toByteArray()
println(test1)
button.setOnClickListener {
if (enter.getText().toString() != "") {
var def = (enter.getText()).toString()
println("def = ${def}")
var test2 = def.toByteArray()
println(test2)
}
}
}
}
Upvotes: 0
Views: 2180
Reputation: 3395
I also found this quite confusing when writing some code to encode then later decode ByteArrays. In short, this code did not produce matching output:
val somebytes = "567".toByteArray()
val somebytesEncoded = Base64.getUrlEncoder().encodeToString(somebytes)
val somebytesDecoded = Base64.getUrlDecoder().decode(somebytesEncoded)
println(somebytes) // output = [B@305fd85d
println(somebytesDecoded) // output = [B@458c1321
and it took quite a while before realizing that despite the different on-screen representation, the encoding/decoding is working properly, and the variables are in fact equal:
println(somebytes.contentEquals(somebytesDecoded)) // true
(one of the clues was that the length of the console output did not change when experimenting with longer string inputs)
Therefore if your goal is to pass a string that can be reliably decoded later, you need to use Java's Base64 functions or some other library, and definitely not use toString()
.
Base64.getEncoder().encodeToString(somebytes) // NTY3
Base64.getEncoder().encodeToString(somebytesDecoded) // NTY3
somebytes.joinToString("") { "%02x".format(it) } // 353637
somebytesDecoded.joinToString("") { "%02x".format(it) } // 353637
And also keep in mind these are not hashing functions, so as your strings get longer, the outputs will also grow longer as well, which may or may not be a concern in your sockets program.
Upvotes: 0
Reputation: 19524
The standard Object.toString()
is class name + @ + hashcode, so here it's big B for an array of bytes, and the array's hashcode at the end.
Problem is, in Java two different array objects with the same contents aren't considered equal (not by their equals
implementation anyway). And though it's not a requirement, it's considered best practice that hashCode()
should return different values for two unequal objects. So that's why when you create another one, it gets a different hash in its string representation.
I don't know for sure, but I wouldn't be surprised if it does a standard hash algorithm each time, and checks to see if another array with that hash exists in memory, adding to the current hash until there are no more collisions. So you get the same results every time you run it with the same data.
Anyway yeah, you can't really use the toString()
output for this, but it doesn't seem like you want to anyway? You just want to use the contents, which should work fine. It's just your test code that's printing the hash instead of the contents
Upvotes: 0
Reputation: 1829
[B@fde8d29
does not represent the value of ByteArray
, it's the return value of ByteArray.toString()
. If you want print ByteArray's value, use this:
fun ByteArray.toHexString() = joinToString("") { it.toString(16).padStart(2, '0') }
val array: ByteArray = "567".toByteArray()
array.toHexString()
Upvotes: 1