【问题标题】:Converting a string in a hexa with 21 chars用 21 个字符将字符串转换为 hexa
【发布时间】:2013-08-08 11:56:10
【问题描述】:

我有一项与另一个应用程序集成的服务,它只接受 21 个十六进制字符。我需要传递并接收一个包含 11 个十进制字符的字符串,例如:String s = "0101230154V";

我想知道,如何使用移位操作将其转换为位并传输,因为我无法将十进制字符串转换为十六进制,因为它会产生 22 个十六进制字符。我试过下面的代码。我认为可以进行六进制转换,但是当我尝试转换回十进制表示法时它不起作用,请给我其他值。我认为程序员 C#、C++ 和 Java 可以帮助我。

int n = 99;  // 2^6 bits to use 99
int k = 999; // 2^9 bits to use 999

int bits = (n << 6) | (k << 9 << 6); // I'm not sure if it is ok to convert and use with hexa

var hexa = bits.ToString("X"); // I will transmit this hexa to a web service

在另一个项目中,我有一个 Windows 服务来从 Web 服务中读取 hexa。我可以正常阅读,但我不知道如何转换回十六进制值并以 nk 值为例:

string hexa = GetFromWebService(); // get from the value from the web service here, its fine

// I will recieve the hexa and get the number in bits
int received = Int32.Parse(hexa, System.Globalization.NumberStyles.HexNumber);

// here I need to discover the N and K values... how?

如何发现nk 值?

最终解决方案

long v = 123456789456;
string h = v.ToString("X");

// trasmit h value

var data = long.Parse(hexaValueFromService, System.Globalization.NumberStyles.HexNumber);

谢谢

【问题讨论】:

  • 你的问题让我有点困惑。您的示例 String s = "0101230154V"; 确实包含 11 个字符,但最后一个字符不是十进制的。这是笔误吗?
  • 我认为他的意思是十进制的 11。
  • 字符串中允许使用哪些字符?显然,如果可以有 256 个选项(或更多),则不能将其编码为少于 22 个字符的十六进制字符串。
  • 我更新了我的问题伙计们,我认为它更容易理解。 Tks

标签: c# java c++ bit-manipulation shift


【解决方案1】:

我不知道您说“11 个十进制字符”时是否有错字,因为最后一个字符显然不是十进制或十六进制数字。

如果这是一个真正的错字,11 个十进制字符的最大值为 99 999 999 999,它适合 64 位 int,仅对应于 16 个十六进制字符。因此,您可以将字符串转换为int64_t (C++)/long (C#/Java),然后传递给其他服务。

如果不是拼写错误,您仍然可以将前 10 个十进制数字转换为 int64_t,然后同时传递 int64_t 和剩余的字符,只需要 18 个十六进制字符

如果您不想转换为二进制,那么densely packed decimal (DPD) 是一个不错的选择。它将 3 个十进制数字打包成 10 位。所以 10 位需要 34 位,占用 9 个十六进制数字。这直接适用于十进制,不需要转换为二进制,因此不仅占用更少的空间,而且来回转换也非常快。如果您不需要对值进行算术运算,这可能是最佳选择

【讨论】:

  • 你能给我举个例子吗?我真的不喜欢这种方法呵呵
  • 对于您的字符串“0101230154V”,0101230154 = 0x000000000608A64A,V = 0x56 ASCII。因此,您可以将字符串传输为 0x000000000608A64A560000
【解决方案2】:

一个 ASCII 字符占用一个字节或 8 位。 一个 Unicode 字符占用两个字节,即 16 位。 因此,11 个字符的字符串将占用 11 个字节或 22 个字节,具体取决于 CharacterSet。 尝试将 CharacterSet 设置为 ASCII,它会起作用。
在正常打字中,两个十六进制字符存储一个字节。因此,您的服务最多有 90 位输入(10.5 字节)

【讨论】:

  • 一个 Unicode 字符占用两个字节”,这并不完全正确。 Unicode 编码 UTF-8 将字符编码为 1、2、3 或 4 个字节,UTF-16 编码为 2 或 4 个字节,UTF-32 将每个字符编码为 4 个字节。
  • 我认为 java 使用 16 位 Unicode 字符集,但如果我错了,请纠正我
  • 是的,Java 内部使用 UTF-16,因此每个字符编码为 2 或 4 字节(低位和高位代理)。
  • 我更新了我的问题伙计们,我认为它更容易理解。 Tks
  • 不是真的,说实话我更迷茫了。
【解决方案3】:

你能保证字符不会出现在前2位吗?如果是这样,那么您可以将前 2 位的整数放入 k 中。

如果您在通过时左移以抑制前导 '0',一旦获得它,您将再次右移以获取原始数字,而不是解析整数。例如: 如果你这样做:

(n 是 6 位,k 是 9 位)所以,你想将它们组合成位(15 位,第 16 位是符号位,所以不会使用它)

int bits =   (k << 6) | n

当您收到时,您必须这样做以检索值:

n = (bits & 0x3F)     // gets rid of k in the first part 0x3F means '0000000000111111'
k = (bits >> 6)       // gets rid of n at the bottom part

【讨论】:

  • 朋友您好,谢谢您的回答。我正在测试它,k 运行良好,但n 不行。为什么 k 是 10 位而不是 os 9?
  • 使用 9 位,您可以达到 512。您需要 10 位才能达到 999。无论如何都改变了我的答案,因为我们不应该使用第 16 位,即符号位;也需要 7 位才能达到 99。立即尝试
  • 奇怪,n 是 35 而 k 是 999(好的)。我将n 的初始值更改为12 并将k 更改为452.. 两者都很好,当n99(最大可能值)时,它出现35..
  • 正如我所说,您可以分别使用 6 位和 9 位达到 63 和 511...对于 99 和 999,您分别需要 7 位和 10 位。你能在 n 和 k 中使用 99 和 99 吗?那么你需要 7 + 7 = 14 位并且很容易在 int 类型中完成。在这种情况下 int bits = (k > 7
  • n 的最大可能值为 99,k 为 999。这就是我尝试使用这些值的原因。我已经对此进行了测试:int bits = (k &lt;&lt; 7) | n; 并转换为:n= (bits &amp; 255); k = bits &gt;&gt; 7。我得到所有值都很好,但我不知道为什么255,这是因为 255 是 2^7-1(-1 因为符号)?
猜你喜欢
  • 2019-08-01
  • 1970-01-01
  • 2019-10-10
  • 2011-03-14
  • 1970-01-01
  • 2019-01-05
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多