【问题标题】:Swift string to Hex (Not Array)Swift字符串到十六进制(不是数组)
【发布时间】:2017-06-29 17:58:43
【问题描述】:

我想创建一个类型(标签)、长度、值(TLV)字节数组。

https://en.wikipedia.org/wiki/Type-length-value

此 TLV 将是一个 [UInt8] 数组,其中前两个元素是类型/标签和长度,其余元素是编码字符串的字节。例如。 “你好,世界。”

我在 Swift 中这样做。

我希望值部分是一个可行的长度字符串。

我可以轻松创建类型(标签)和长度。例如:

let tag: UInt8    = 0x02
let length: UInt8 = 0x01

当我以以下方式从字符串创建字节数组时:

let str = "Yo, El Mundo"
let buf = [UInt8](str.utf8)

我得到了一个合适的数组。但是,当我尝试将其添加到 [UInt8] 数组时,我从 Xcode 收到以下错误:

Cannot convert value of type '[UInt8]' to expected element type 'UInt8'

这里要非常清楚的是产生这个错误的代码:

let tag: UInt8   = 0x02
let length: UInt8 = 0x01

let str = "Yo, El Mundo"
let buf = [UInt8](str.utf8)
print("the buf is: \(buf)")
// the buf is: [89, 111, 44, 32, 69, 108, 32, 77, 117, 110, 100, 111]

let bytes:[UInt8] = [tag, length, buf]

// Error: Cannot convert value of type '[UInt8]' to expected element type 'UInt8'

这是我不了解的部分。我假设问题出在格式上。 IE。我假设问题是我试图在数组中放入“[89,111,44,32,69,108,32,77,117,110,100,111]”而不是“0x01”。

但也许我只是不明白别的东西。我对以字节为单位工作完全陌生,所以我仍在学习我不知道的东西。

我需要想办法将字节数组转换为更小的十六进制格式吗?

我还错过了什么吗?

只是在寻找一点方向。

抱歉,不清楚。尽我所能 - 这就是我在这里问的原因。

谢谢

【问题讨论】:

  • 你的问题很不清楚。 “从那个字符串创建一个十六进制”是什么意思
  • 看起来你想要一个[UInt8],其中前两个元素是taglength,其余元素是编码字符串的字节(请明确说明你的编码想使用,你的代码虽然说 UTF-8)。虽然我会从Data而不是[UInt8]开始,然后转换为Data。另请注意,十六进制只是一种以人类可读的方式呈现字节的方式(就像十进制一样)——它与它们在内存中的存储方式无关。它们在一天结束时只是零和一(即使这仍然只是一种呈现它们的方式)。
  • [89, 111, 44, 32, 69, 108, 32, 77, 117, 110, 100, 111] 是一组存储位的十进制表示。 “十六进制”不是一种存储方式,而是一种表示它们的方式。
  • 为什么要将字符串转换为单个字节?什么是 TLV?同样,您的问题确实不清楚。
  • 以更明确的方式解释您的错误:var bytes = [UInt8].init(); bytes.append(tag); bytes.append(length); bytes.append(contentsOf: buf) 如您所见,buf 已经是[UInt8],所以我使用append(contentOf:) 来代替每个元素一个接一个地附加..所以如果你做了[tag, length, buf],那将是一个[FirstUInt8, SecondUInt8, ArrayOfUInt8],所以它需要被声明为[Any]let bytes2:[Any] = [tag, length, buf](打印两者,你会看到区别)。

标签: arrays swift string


【解决方案1】:

问题出在您的buf 变量中,它的类型是[UInt8],而不是预期的UInt8。您还可以为Data[UInt8] 创建一个extension 以创建十六进制表示。下面的代码可以根据需要正确连接数据。

import Foundation

extension Data {
    var hex: String {
        let stringDataParts = self.map { String(format: "%02.2hhx", $0) }
        let stringData = stringDataParts.joined()
        return stringData
    }
}

let tag: UInt8   = 0x02
let length: UInt8 = 0x01

let str = "Yo, El Mundo"
let buf = [UInt8](str.utf8)
print("the buf is: \(buf)")
// the buf is: [89, 111, 44, 32, 69, 108, 32, 77, 117, 110, 100, 111]

let bytes:[UInt8] = [tag, length] + buf

print(bytes)
// [2, 1, 89, 111, 44, 32, 69, 108, 32, 77, 117, 110, 100, 111]

print(Data(bytes: bytes).hex)
// 0201596f2c20456c204d756e646f

【讨论】:

  • 最优秀的瓦尔卡纳亚!感谢您提供我缺少的信息!这太棒了。因此,为了清楚起见,我个人的误解是必须将字符串放入数组中。该数组需要连接,然后附加到字节数组中。非常感谢你的帮助。代码现在运行良好。
猜你喜欢
  • 1970-01-01
  • 2021-08-11
  • 2010-10-04
  • 2011-04-14
  • 2021-03-11
  • 1970-01-01
  • 2012-05-30
  • 2013-08-09
  • 2013-10-13
相关资源
最近更新 更多