字符串加密 - 生成类似Spotify代码的唯一模式

4
昨天我读了一个问题,链接为Algorithm to create costum Template/Code from String。由于问题表述不清晰,它很快就被downvote了。然而,在我看来这个问题本身并不那么糟糕,所以我决定重新提出一个更好的问题。
我想知道像新版Spotify代码这样的字符串加密是如何工作的,如下图所示: Spotify Codes 引用:

我非常想知道在Javascript中是否可能实现类似这种模式加密。

Spotify代码(如上文所述)结构化成一排,由不同大小的条形组成。
假设有一排被分成了24个条形,所有条形的大小可以是'3','5','7'或'9'。
 string = 'hello'   -->  pattern = '3,3,5,7,9,3,7,9,9,3,3,5,3,9,5,3,3,7,5,9,3,9,3,9'

什么是将字符串(假设为5个字符)转换为唯一模式的好方法/简单方法,之后也可以将其转换回字符串?
这是我迄今为止开发的代码,但在这段代码中,我使用了一个包含10种不同可能性(-->条形码大小)的键数组,但我只想使用4种不同大小。
说明:
我将字符串“hello”转换为二进制格式,并将字符串拆分成最多3个组,以获得以下结果:['001','110','0']。
然后,我使用上面的结果数组,在下面的密钥数组中查找匹配项并获取索引(10个不同的索引--> 10个不同的可能性),并将它们用作条形码大小。
但是,肯定有更有效的方法将字符串转换为唯一模式。我希望有人能帮助我改进我的小算法。非常感谢您的帮助。

var key = ['0', '1', '000','001','010','100','110','101','011','111']


String.prototype.encode = function() {
  var code = this, result = [],encryped_string=[]
  for (var i=0; i<code.length;i++) result.push(code[i].charCodeAt(0).toString(2).match(/.{1,3}/g));
  for (var i=0; i<result.length; i++) for (var j=0; j<result[i].length; j++) encryped_string.push(key.indexOf(result[i][j]))
  return encryped_string
}



var code = 'hello';
console.log(code.encode())


  1. 10是怎么回事?你不需要前两个条目。
  2. 如果你想处理Unicode,你需要处理每个字节的所有8位和每个字符的多个字节,UTF-8可能是最好的选择。Unicode对于大多数世界和表情符号是必需的。
- zaph
2个回答

6

你似乎认为从字符串“Coffee”到显示的图形之间存在直接映射关系,这种假设几乎肯定是不正确的。

首先,考虑一下如果有两首不同的歌曲名叫“Coffee”会发生什么。你提出的算法将把它们都分配给同一个代码。这似乎是不合理的。你需要让代码能够 唯一标识 每首歌曲。

其次,歌曲名可以任意长。例如,粉红弗洛伊德(Pink Floyd)有一首歌叫“Several Species of Small Furry Animals Gathered Together in a Cave and Grooving with a Pict”。你的编码算法可能无法将其放入24栏中。即使它能够,我仍然可以找到一个更长的歌曲标题。

给定字母a-z,有11,881,376个可能的5字符字符串。如果你只想唯一编码所有可能的字符串,可以使用23位完成。只需将字符串视为基于26的数字进行转换。

最有可能的是,Spotify为每首歌曲分配了一个唯一的编号,然后对该编号进行编码。字符串“Coffee”和你在屏幕上看到的图形代码之间没有直接的映射关系。


6
更新:我曾提出过类似的问题,有人通过链接此二维码的专利来回答了我的问题。简而言之,他们使用一个中介查找表来将二维码与独特的 Spotify ID 相关联。
我一直在深入研究 Spotify 代码,试图理解它们。
Spotify 为每首歌曲、每个专辑、每位艺术家、每个用户、每个播放列表等都设置了 URI。它们看起来像这样:
spotify:playlist:37i9dQZF1DXcBWIGoYBM5M
如果你访问 Spotify Codes,你可以从 URI 生成一个代码。上面这个 URI 对应的代码如下:

Image of a spotify barcode

正如您所指出的那样,Spotify Codes中的每个条形码都将信息编码在每个条形码的高度上,就像美国邮政服务在其条形码中所做的那样(请参见智能邮件条形码)。
Spotify Codes中的条形码有8种不同的高度。标志是最大高度,第一个和最后一个条形码始终是最低高度。在上图中,最大高度为96像素,条形码分为8个不同的高度区间:[96, 84, 74, 62, 52, 40, 28, 18]
使用这段(有点凌乱的)Python代码,我可以从条形码图像中获取八进制序列:
from skimage import io
from skimage.filters import threshold_otsu
from skimage.measure import label, regionprops
from skimage.morphology import square
from skimage.color import label2rgb, rgb2gray

def get_sequence(filename):
    image = io.imread(filename)
    image = rgb2gray(image)
    b_and_w = image > threshold_otsu(image)
    labeled = label(b_and_w)
    bar_dims = [r.bbox for r in regionprops(labeled)]
    bar_dims.sort(key=lambda x: x[1], reverse=False)
    spotify_logo = bar_dims[0]
    max_height = spotify_logo[2] - spotify_logo[0]
    sequence = []
    for bar in bar_dims[1:]:
        height = bar[2] - bar[0]
        ratio = height / max_height
        if ratio < 0.25:
            sequence.append(0)
        elif ratio < 0.33:
            sequence.append(1)
        elif ratio < 0.46:
            sequence.append(2)
        elif ratio < 0.5625:
            sequence.append(3)
        elif ratio < 0.677:
            sequence.append(4)
        elif ratio < 0.8:
            sequence.append(5)
        elif ratio < 0.9:
            sequence.append(6)
        elif ratio < 1.1:
            sequence.append(7)
        else:
            raise ValueError('ratio is too high')
    return sequence

序列映射如下:37i9dQZF1DXcBWIGoYBM5M -> [0, 6, 0, 2, 4, 5, 1, 4, 5, 2, 3, 7, 3, 7, 1, 5, 6, 2, 5, 7, 4, 3, 0] 奇怪的是URI和Spotify代码中的信息量不匹配。URI长度为22个字符,包含0-9 a-z A-Z。这意味着可能有62^22个URI或2.7 e39个URI。Spotify代码中有23个条形码,但第一个和最后一个始终为0,因此只有21个可用条形码。这意味着可能有8^219.22 e18个潜在代码。URI到代码的映射并不简单,因为没有一个代码对应一个URI。
我不知道他们如何将URI映射到代码。 我猜想他们有一个单独的数据库/查找表,用于将代码映射到URI。 创建代码时,他们将URI哈希为代码并存储以供以后查找。 当有人查找代码时,他们检查该数据库并将其映射到URI。 由于潜在的URI太多,它们根本不会被使用,因此他们不必担心它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接