将任何ASCII字符串唯一编码为使用ASCII子集的字符串



对于这个问题,请假设是python,但这并不一定重要。

假设您有一个任意的ASCII字符串,例如:

jrioj4oi3m_=.,ei9#

省去了大量的细节,我需要将这个字符串作为";标签";转到另一个程序,但该程序不支持";标签";包含";特殊字符";或偶数。因此,我试图将ASCII字符串编码为使用任意ASCII子集的字符串。

一个非常天真的解决方案是将原始字符串转换为二进制,然后将0转换为"0";a";并将1s转换为"1";b";。这可以解决我的问题,但我想在这里学习更好的解决方案,成为一名更好的程序员。

首先,这个问题到底叫什么?

这并不完全是一个哈希问题,因为IIRC哈希通常涉及编码到比原始字符串更短的字符串中,并且涉及冲突。

我需要没有冲突,并且我真的不在乎编码的字符串有多长,只要它比天真的情况更短。(理想情况下,它将是给定子集的最短长度(

事实上,最好指定允许的字符集是什么,然后使用通用编码算法进行编码。

解码也很高兴知道。

一个简单的解决方案是首先转换为十六进制编码:

  • jrioj4oi3m_=.,ei9#=>6a72696f6a346f69336d5f3d2e2c65693923

,然后将任何数字转换为非十六进制字母:

  • 6a72696f6a346f69336d5f3d2e2c65693923=>waxswzwfwatuwfwzttwdvftdsescwvwztzst

因此,输出字符串的长度总是输入字符串长度的两倍,并且只包含a-z范围内的字符。

这可以在python中轻松实现,如下所示:

>>> enc = str.maketrans('0123456789', 'qrstuvwxyz')
>>> dec = str.maketrans('qrstuvwxyz', '0123456789')
>>> s = 'jrioj4oi3m_=.,ei9#'
>>> x = s.encode('ascii').hex().translate(enc)
>>> x
'waxswzwfwatuwfwzttwdvftdsescwvwztzst'
>>> bytes.fromhex(x.translate(dec)).decode('ascii')
'jrioj4oi3m_=.,ei9#'

有趣的是,这实际上是一个非常简单和常见的数学问题:基转换。作为一名程序员,你可能知道,至少在理论上,如何在一个值的基数2、10和16之间转换。有96个可打印的ASCII字符,因此任何ASCII字符串都可以被认为是一个(可能非常大(值的96进制表示。如果您的标签只接受64个字符(例如,大写、小写、数字和2个其他字符(,那么您只需要将96进制表示转换为相同值的64进制表示。解码就是简单地将64进制表示转换回96进制表示。

最新更新