【问题标题】:How to convert a hex value back to an ASCII string?如何将十六进制值转换回 ASCII 字符串?
【发布时间】:2016-12-30 10:47:17
【问题描述】:

我正在尝试从我的 Arduino 设备上通过 BLE 读取加速度计。唯一的问题是我不确定如何将其转换回可读的字符串值。

我的 Arduino 草图(部分)如下所示:

if((x - lastX) > threshold) {
  STATUS = "MOVING";
  toggleIsMoving();
} else if((y - lastY) > threshold) {
  STATUS = "MOVING";
  toggleIsMoving();
} else if((z - lastZ) > threshold) {
  STATUS = "MOVING";
  toggleIsMoving();
} else {
  STATUS = "STOPPED";
  toggleIsStopped();
}
lastX = x;
lastY = y;
lastZ = z;
Serial.print(STATUS);

我在 Xamarin Android 应用程序(通过 BLE)中收到的十六进制值是这样的:

A0-08-00-00-00-4D-4F-56-49-4E-47-CE-3C

我目前的实现是:

public static string FromHex(string hex) {
  hex = hex.Replace("-", "");
  byte[] raw = new byte[hex.Length / 2];
  for (int i = 0; i < raw.Length; i++)
    raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
  return Encoding.ASCII.GetString(raw);
}

这个结果是:

?������移动?

为什么会发生这种情况,如何将其转换回 C# 中的可读字符串?

更新 1

我对bean-sdk源代码做了一些研究,发现了这个:

/**
   * Represents a LightBlue Serial Transport Message
   *
   * Defined as:
   *
   *    [1 byte]         - Length     (Message ID + Payload)
   *    [1 byte]         - Reserved
   *    [2 byte]      BE - Message ID
   *    [0-64 bytes]  LE - Payload
   *    [2 bytes]     LE - CRC        (Everything before CRC)
   *
   * @param messageId
   * @param definition
   */

更新 2

最终通过实现更新 1 中提到的协议使其工作。实际的有效负载位于内部,因此需要从十六进制字符串中提取。

【问题讨论】:

  • A0-08-00-00-00 的值超出了正常的打印范围,所以给你一些不稳定的字符..

标签: c# arduino hex bluetooth-lowenergy


【解决方案1】:

任何超过 0x7F 的都是 不是 ASCII。第一个字符是 0xA0。其中,Unicode 和 IOS LATIN 1 都是 NBSP。序列A0-08-00-00-00 可能有意义,但不是纯文本方式。你应该看看你的加速度计的规格,看看它吐出什么来正确解释它。

编辑

另外,由于您在代码中将变量 STATUS 设置为“MOVING”,因此 MOVING 前后的字符可能是虚假字符。

【讨论】:

  • 在此分析中,Unicode 表示字符集,并且您对 Unicode 使用 UTF-8 编码 (Encoding.UTF8)(与 Unicode Encoding.Unicode 的 UTF-16 编码相反)。
  • 好的,这是我正在使用的板子:punchthrough.com/bean/docs/guides/features/accelerometer
  • 错了,UTF-8 中没有 0x00A0。拉丁语 1 的 A0,UTF-16 0x00A0,在 UTF-8 中是 0xC2A0...
  • 但是关于 Unicode 和它的编码之间的混淆的好点。
  • @dda 哎呀,你说得对,它不是 UTF-8。无论如何,正如您所指出的,它可能并非全是文本。
【解决方案2】:

我用过以下:

private static string hexToASCII(string hexValue)
{
    StringBuilder output = new StringBuilder("");
    for (int i = 0; i < hexValue.Length; i += 2)
    {
        string str = hexValue.Substring(i, 2);
        output.Append((char)Convert.ToInt32(str, 16));
    }
    return output.ToString();
}

参考:从Convert Hex to ASCII and ASCII to Hex处的Java函数转换

【讨论】:

  • 此代码使用 ISO 8589-1 字符集及其一种拜占庭方式的编码。 Unicode 的前 256 个代码点与整个 ISO 8589-1 字符集相同。 char 是一个 UTF-16 代码单元。 UTF-16 是 Unicode 字符集的编码。 UTF-16 恰好使用一个高字节为 0 的 16 位代码单元对 Unicode 的前 256 个代码点进行编码。因此,将两个十六进制数字字符转换为整数,然后转换为 char 可以有效地将数据解码为 ISO 8589 -1 文本。
猜你喜欢
  • 1970-01-01
  • 2017-03-11
  • 2014-11-16
  • 2015-05-22
  • 1970-01-01
  • 2017-06-16
  • 2018-01-22
  • 2011-11-21
  • 2019-02-13
相关资源
最近更新 更多