我正在尝试获取 21 个字节的数据来唯一标识交易并将其存储在一个 16 字节的 char 数组中。我无法为此提出正确的算法。
我要压缩的交易 ID 包含 2 个字段:
因此,包含这些数据的 C++ 类如下所示:
class ID
{
public:
char trade_num_[18];
char broker_[3];
};
这个数据需要存储在一个16-char的数据结构中,如下所示:
class Compressed
{
public:
char sku_[16];
};
我试图利用这样一个事实,因为 trade_num_ 中的字符只有 0-127,每个字符中有 1 个未使用的位。类似地,二进制的 999 是 1111100111,它只有 10 位——比 2 字节字少 6 位。但是当我计算出我能压缩多少时,我能做到的最小是 17 个字节;一个字节太大了。
有什么想法吗?
顺便说一句,trade_num_ 用词不当。它可以包含字母和其他字符。规范就是这么说的。
编辑:很抱歉造成困惑。 trade_num_ 字段确实是 18 个字节,而不是 16 个字节。在我发布这个帖子后,我的互联网连接中断了,直到现在我才能回到这个帖子。
EDIT2:我认为对数据集做出假设是安全的。对于 trade_num_ 字段,我们可以假设不存在不可打印的 ASCII 字符 0-31。 ASCII 码 127 或 126 (~) 也不会。所有其他可能都存在,包括大小写字母、数字和标点符号。这样一来,trade_num_ 将包含 94 个字符,ASCII 码 32 到 125,包括 32 到 125。
最佳答案
如果您有 0 - 127 范围内的 18 个字符和 0 - 999 范围内的数字并尽可能压缩它,那么它将需要 17 个字节。
>>> math.log(128**18 * 1000, 256)
16.995723035582763
您也许可以利用某些字符很可能不使用这一事实。特别是不太可能有任何低于值 32 的字符,并且也可能不使用 127。如果你能找到更多未使用的字符,那么你可以先将这些字符转换为 base 94,然后将它们尽可能紧密地打包到字节中。
>>> math.log(94**18 * 1000, 256)
15.993547951857446
这个刚好适合16个字节!
示例代码
这里是一些用 Python 编写的示例代码(但以非常命令式的风格编写,以便非 Python 程序员可以轻松理解)。我假设输入中没有波浪号 (~)。如果有,您应该在编码字符串之前用另一个字符替换它们。
def encodeChar(c):
return ord(c) - 32
def encode(s, n):
t = 0
for c in s:
t = t * 94 + encodeChar(c)
t = t * 1000 + n
r = []
for i in range(16):
r.append(int(t % 256))
t /= 256
return r
print encode(' ', 0) # smallest possible value
print encode('abcdefghijklmnopqr', 123)
print encode('}}}}}}}}}}}}}}}}}}', 999) # largest possible value
输出:
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[ 59, 118, 192, 166, 108, 50, 131, 135, 174, 93, 87, 215, 177, 56, 170, 172]
[255, 255, 159, 243, 182, 100, 36, 102, 214, 109, 171, 77, 211, 183, 0, 247]
此算法使用 Python 处理非常大的数字的能力。要将此代码转换为 C++,您可以使用大整数库。
你当然需要一个等效的解码函数,原理是一样的——操作是按相反的顺序进行的。
关于c++ - 将 21 个字母数字字符压缩为 16 个字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3419606/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解