我有一个字符串,通过使用string.format("%02X", char)
,我收到了以下内容:
74657874000000EDD37001000300
最后,我希望这个字符串看起来如下:
t e x t NUL NUL NUL í Ó p SOH NUL ETX NUL
(这里有空格只是为了澄清示例中所需的字符)。
我已经尝试过使用x..(hex#)
、string.char(0x..(hex#))
(其中(hex#)
是我想要的字符的字母数字表示),但我仍然无法获得我想要的结果。在阅读了关于这个主题的另一个帖子:在lua中表示unichar的方法是什么以及答案中提供的链接之后,我还没有完全理解在我的最终代码中需要做什么,这是可以接受的。
我正在寻求一些帮助,以更好地理解一种方法,帮助我实现下面提供的预期结果。
ETA:
我以为我已经用以下代码修复了它:
function hexToAscii(input)
local convString = ""
for char in input:gmatch("(..)") do
convString = convString..(string.char("0x"..char))
end
return convString
end
它似乎起了作用,但没有考虑127以上的字符。新手失误。现在我不确定如何让最多256个附加字符显示它们的ASCII值。
我做了以下检查,因为我无法在文件中真正"看到"它们。
function asciiSub(input)
input = input:gsub(string.char(0x00), "<NUL>") -- suggested by a coworker
print(input)
end
我做了一些gsub
字符串来替换其他字符,我的文件返回时带有替换字符串。但当我在扩展ASCII表中遇到字符时,一切都忘记了。
有人能帮助我了解这个问题的解决方案或新方法吗?正如我之前所说的,我读过其他关于这个问题的话题,仍然对解决这个问题的最佳方法感到困惑。
将base16编码字符串转换为的简单方法
function unhex( input )
return (input:gsub( "..", function(c)
return string.char( tonumber( c, 16 ) )
end))
end
这基本上就是你所拥有的,只是稍微干净一点。(没有必要说"(..)"
,".."
就足够了——如果你不指定捕获,你会自动得到整个匹配。虽然如果你写string.char( "0x"..c )
,它可能会起作用,但它只是邪恶的——你连接了很多字符串,然后触发自动转换为数字。显式转换时只指定基数要好得多。)
无论编码如何,得到的字符串都应该与进入十六进制转储程序的字符串完全相同。
如果无法正确显示结果,则查看器也将无法显示原始输入。如果您对原始输入和结果输出使用了不同的查看器(例如,文本编辑器和终端),请尝试将输出写入文件,并使用与原始输入相同的查看器进行查看,那么两者应该完全相同。
让假设不同编码的查看器(例如,一个"旧"的8位代码页或许多版本的Unicode中的一个)显示相同的内容将需要在不同格式之间进行转换,这往往非常复杂,甚至不可能。由于您没有提到所涉及的编码(也没有提到任何其他信息,如操作系统或使用的程序,这些信息可能会暗示可能的编码),所以这可能只是任何内容,因此不可能有更具体的内容。
您实际上有几个问题:
-
首先,确保您知道术语字符编码的含义,并且您知道字符和字节之间的区别。关于这个话题的一个流行帖子是每个软件开发人员绝对、积极地必须知道的关于Unicode和字符集的绝对最小值(没有借口!)
-
那么,您刚刚收到的字节使用了什么编码?你需要知道这一点,否则你不知道字节234是什么意思。例如,它可以是ISO-8859-1,在这种情况下,它是U+00EA,字符ê。
-
字符0到31是控制字符(例如,0是
NUL
)。使用查找表进行查找。 -
那么,在终端上显示字符是最困难的部分。没有独立于平台的方式在终端上显示ê。使用标准的
print
函数,这很可能是不可能的。如果你不能解决这个问题,你可以搜索一个问题,专门处理如何从Lua中打印Unicode文本。