【问题标题】:How can I properly output a ByteArray?如何正确输出 ByteArray?
【发布时间】:2021-07-30 06:38:45
【问题描述】:

我为toByteArray() 做了一个测试代码。 abc 变量接收一个String "567" 并将其转换为ByteArray 并输出,总是这样写。

I/System.out: abc = 567

I/System.out: [B@fde8d29

但是,当我在EditText 中输入"567" 作为字符串并将其转换为ByteArray 时,值总是以不同的方式写入,如下所示。

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

我正在实现一个套接字程序,我需要在EditText 中获取一个String 并将其发送到字节序列中,但是值总是在变化。 我该如何解决这个问题?

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)
            }
        }

    }
}

【问题讨论】:

  • "这些值的写法总是不同的,如下所示。":每个toByteArray() 调用都会创建一个ByteArray 的新实例。将此传递给 println 会调用 toString 函数,该函数会为您提供该特定实例的唯一标识符。

标签: android arrays kotlin


【解决方案1】:

[B@fde8d29不代表ByteArray的值,是ByteArray.toString()的返回值。如果要打印 ByteArray 的值,请使用:

fun ByteArray.toHexString() = joinToString("") { it.toString(16).padStart(2, '0') }
val array: ByteArray = "567".toByteArray()
array.toHexString()

【讨论】:

    【解决方案2】:

    标准的Object.toString()类名+@+哈希码,所以这里是字节数组的大B,数组的哈希码在最后。

    问题是,在 Java 中,两个具有相同内容的不同数组对象被认为是相等的(无论如何,它们的equals 实现不是)。虽然这不是必需的,但 considered best practice 应该是 hashCode() 应该为两个不相等的对象返回不同的值。所以这就是为什么当你创建另一个时,它的字符串表示形式会得到不同的哈希值。

    我不确定,但如果它每次都执行标准哈希算法并检查内存中是否存在具有该哈希的另一个数组,添加到当前哈希直到有没有更多的碰撞。因此,每次使用相同的数据运行它时,您都会得到相同的结果。

    无论如何,您不能真正为此使用toString() 输出,但您似乎不想这样做?您只想使用内容,这应该可以正常工作。只是您的测试代码在打印哈希而不是内容

    【讨论】:

      【解决方案3】:

      在编写一些代码来编码然后解码 ByteArrays 时,我也发现这很令人困惑。总之,这段代码没有产生匹配的输出:

      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
      

      花了很长时间才意识到尽管屏幕上的表现不同,编码/解码工作正常,变量实际上是相等的:

      println(somebytes.contentEquals(somebytesDecoded)) // true
      

      (其中一个线索是,在尝试更长的字符串输入时,控制台输出的长度没有改变)

      因此,如果您的目标是传递一个以后可以可靠解码的字符串,则需要使用 Java 的 Base64 函数或其他一些库,绝对不要使用toString()

      Base64.getEncoder().encodeToString(somebytes)         // NTY3
      Base64.getEncoder().encodeToString(somebytesDecoded)  // NTY3
      
      somebytes.joinToString("") { "%02x".format(it) }        // 353637
      somebytesDecoded.joinToString("") { "%02x".format(it) } // 353637
      

      还要记住,这些不是散列函数,所以当你的字符串变长时,输出也会变长,这可能是你的套接字程序中的一个问题,也可能不是。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-27
        • 2017-12-14
        • 2014-03-08
        • 1970-01-01
        • 2022-09-27
        • 1970-01-01
        相关资源
        最近更新 更多