Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 如何仅使用数字(数字字符)对8字节块进行编码?_Language Agnostic_Encoding - Fatal编程技术网

Language agnostic 如何仅使用数字(数字字符)对8字节块进行编码?

Language agnostic 如何仅使用数字(数字字符)对8字节块进行编码?,language-agnostic,encoding,Language Agnostic,Encoding,我需要对8字节的流进行编码,这样编码的流中只有数字(0到9)。他们有没有标准的编码机制来实现这一点?如果有多种方法可以做到这一点,那么就编码字符串的长度而言,哪种方法是有效的(越短越好)?将8个字节视为64位无符号整数,将其转换为十进制,并用零填充到左侧。这应该是尽可能短的字符串,因为它在所有位置使用所有可用的数字,除了起始位置 如果您的数据分布不均匀,还有其他选择,可以研究哈夫曼编码,以便最常见的数据模式可以用较短的字符串表示。一种方法是使用第一个数字对字符串的长度进行编码。除第一个位置的1之

我需要对8字节的流进行编码,这样编码的流中只有数字(0到9)。他们有没有标准的编码机制来实现这一点?如果有多种方法可以做到这一点,那么就编码字符串的长度而言,哪种方法是有效的(越短越好)?

将8个字节视为64位无符号整数,将其转换为十进制,并用零填充到左侧。这应该是尽可能短的字符串,因为它在所有位置使用所有可用的数字,除了起始位置

如果您的数据分布不均匀,还有其他选择,可以研究哈夫曼编码,以便最常见的数据模式可以用较短的字符串表示。一种方法是使用第一个数字对字符串的长度进行编码。除第一个位置的1之外的所有数字都可以被视为长度说明符。这样,将永远不会超过20位的最大长度。(第20位数字只能是0或1,最高64位数字是18446744073709551615。)其他数字到长度的精确解释映射应基于模式的分布。如果您有10个经常出现的模式,您可以保留“0”表示一个数字代表一个完整的序列


然而,任何这种更复杂的编码都需要更复杂的打包/解包代码,甚至可能需要查找表,因此可能不值得这样做。

长度最短的结果是直接将其转换为十进制。这导致最大值为
18446744073709551615
,但如果没有任意长度的整数功能,转换可能会很困难

下一个最长的方法是将其转换为八进制作为一个块。这导致最大长度为22,值为
1777
。这只需要转换班次,并且可以很容易地处理


其次是将其转换为八进制或十进制字节。这导致长度为24,分别重复8次
377
255
。来回转换很简单,留给读者作为练习。

效率问题的答案在很大程度上取决于8字节块中的典型值范围。考虑Unicode的UTF-8和UTF-16。UTF-8对于主要用西文脚本编写的文本编码非常有效,因为这些脚本中的大多数字符都在0x00到0x7F的范围内,UTF-8可以存储在单个字节中。但对于主要用东方文字书写的文本编码来说,它不是很有效;UTF-16或UTF-32是更好的选择

如果你有一个阅读,他们可能会激发一个解决方案。从根本上说,它们的工作原理是允许许多值直接编码到一个字节中,但随后有一个标志(我认为是高阶位,在UTF-8的第一个字节的情况下)指示该字节不能说明全部情况,并且需要下一个字节(或两个、三个或四个)。起始点是UTF-8的一个字节,UTF-16的一个字,但概念类似

现在,您使用的值范围非常小(0-9而不是0-255),显然我不建议尝试直接使用UTF,只是概念。例如,假设你的大部分价值观(直接或通过一些按摩)都低于9000,相当多的价值观都低于9000000,只有少数价值观会让你超出这个范围。您可以采用UTF方法,将块(8字节值)划分为四个数字段,并且每个编码块始终至少有一个段(四个数字)。如果第一段的值(aaaa)介于0000和8999(含)之间,则它是“终端”段-这是实际值。但如果是9aaa,这意味着还有第二个段,你应该看看aaabbb(bbbb是下一个段的值)。如果该值介于0000000和8999999(含)之间,则为终端;但如果是9abbb,就意味着看看aabbbbcccc(cccc是下一个细分市场);等等。我想这会给我们带来:

00000000000000000000-00000000000000008999 -> 4 digits (xxxx) 00000000000000009000-00000000000008999999 -> 8 digits (9xxxxxxx) 00000000000009000000-00000000008999999999 -> 12 digits (99xxxxxxxxxx) 00000000009000000000-00000008999999999999 -> 16 digits (999xxxxxxxxxxxxx) 00000009000000000000-00008999999999999999 -> 20 digits (9999xxxxxxxxxxxxxxxx) 00009000000000000000-08999999999999999999 -> 24 digits (99999xxxxxxxxxxxxxxxxxxx) 09000000000000000000-18446744073709551615 -> 28 digits (999999xxxxxxxxxxxxxxxxxxxxxx) Or special case, just use 26 digits for the last one: (999999xxxxxxxxxxxxxxxxxxxx) 000000000000000-0000000000000008999->4位数字(xxxx) 0000000000000000 9000-0000000000000 8999999->8位数字(9xxxxxxx) 0000000000009000000-0000000000 899999999->12位数字(99XXXXXXXXX) 0000000000 900000000-0000000 89999999999->16位数字(999xxxxxxxx) 0000000 900000000000-0000899999999999->20位数字(999xxxxxxxxxxxxxx) 00000900000000000000-08999999999999999999->24位数字(999999xxxxxxxxxxxx) 09000000000000000000-18446744073709551615->28位数字(999999xxxxxxxxxxxxxxxxxxxx) 或特殊情况下,只需使用26位数字作为最后一位:(999999xxxxxxxxxxxxx) 在这里,最好的情况是四位数字,最坏的情况是28或26,这取决于您是否要对块中的最后一个分段进行特殊处理。比每个块使用20个数字要好得多(可能)

现在,这完全是即兴的,可能没有它可能是有效的,但你得到的想法。反序列化非常容易,序列化可能也不难


你可以看到为什么我开始评论你的典型值是什么。如果它们通常在100000000000000000以上,则上述方法不是直接对它们进行编码的有效方法。但是,如果您的典型值位于高端而不是低端,则可以使用类似的技术,方法是在编码之前稍微调整该值。

但它也将是可变长度的,这需要在流中的块之间使用分隔符,这将是。。。。?(因为已经使用了全部十位数。):-)谢谢你的评论,我已经更正并扩展了我的答案。谢谢你的回答!生活在二进制世界中会让你在一段时间后对十进制世界变得陌生。:)您的第一个建议总是要求每个8字节值有20位数字,这似乎无法满足OP的长度请求(除非他的大多数值确实大于1)