如何阅读Base64 VLQ代码?

时间:2013-10-12 03:55:08

标签: css sass source-maps

我正在尝试了解css源地图的工作原理。我创建了一个非常简单的scss文件。

#navbar {
    color: black;
}

当我编译上面的scss时,我得到以下映射文件。

{
"version": "3",
"mappings": "AAAA,OAAQ;EACP,KAAK,EAAE,KAAK",
"sources": ["test.scss"],
"file": "test.css"
}

当我解码“映射”时,我得到以下值。

0) [0,0,0,0], [7,0,0,8]
1) [2,0,1,-7], [5,0,0,5], [2,0,0,2], [5,0,0,5]

这些价​​值观是什么?

4 个答案:

答案 0 :(得分:3)

我在http://www.thecssninja.com/javascript/source-mapping处找到了一个示例,在" Base64 VLQ部分下,保持源地图较小"。

  

上面的图AAgBC一旦进一步处理将返回0,0,32,16,1 - 32是连续位,有助于构建以下16的值.B在Base64中纯粹解码为1.所以重要的值是使用的是0,0,16,1。然后让我们知道第1行(由冒号保持行数)生成的文件的第0列映射到文件0(文件0的数组是foo.js),第1栏第16行。

答案 1 :(得分:3)

http://www.murzwin.com/base64vlq.html可以帮助您编码/解码SourceMap V3和Base64 VLQ数据。

答案 2 :(得分:1)

尽管有我可以找到的例子,但我花了很长时间才了解编码/解码是如何工作的。因此,我认为通过尝试以一种非常明确的,一步一步的方式创造一些东西,我将学到最好的东西。我开始在this blog

解释VLQ

我使用以下Python仿函数为Transcrypt生成源图。 代码很简单,我认为原则上可以很好地理解编码/解码的工作原理。 为了实现速度,尽管它很简单,它会缓存前256个数字,这些数字最常用于生成v3源图。

import math

class GetBase64Vlq:
    def __init__ (self):
        self.nBits32 = 5
        self.encoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
        self.prefabSize = 256
        self.prefab = [self (i, True) for i in range (self.prefabSize)]

    def __call__ (self, anInteger, init = False):
        if not init and 0 < anInteger < self.prefabSize:
            return self.prefab [anInteger]
        else:
            signed = bin (abs (anInteger)) [2 : ] + ('1' if anInteger < 0 else '0')
            nChunks = math.ceil (len (signed) / float (self.nBits32))
            padded = (self.nBits32 * '0' + signed) [-nChunks * self.nBits32 : ]
            chunks = [('1' if iChunk else '0') + padded [iChunk * self.nBits32 : (iChunk + 1) * self.nBits32] for iChunk in range (nChunks - 1, -1, -1)]
            return ''.join ([self.encoding [int (chunk, 2)] for chunk in chunks])

getBase64Vlq = GetBase64Vlq ()

使用示例:

while (True):
    print (getBase64Vlq (int (input ('Give number:'))))

答案 3 :(得分:0)

即使在阅读了答案之后,对我来说解释仍然不清楚。如果有帮助,请使用简单的英语说明:

类似;;AAAA,IAAM,WAAW,SAAX;...的意思是<line0 info>;<line1 info>;...

因此对于;;AAAA;IAAM,WAAW,SAAX;...,第0行和第1行没有任何重要信息(空空格等)

然后对于第2行,我们有AAAA,IAAM,WAAW,SAAX

我们使用base64字符映射将每个组转换为二进制:

BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

因此,我们基本上在上面的BASE64_ALPHABET中找到了索引,并将索引转换为6位二进制(6位,因为我们使用base64)。例如。 A的索引为0,因此在6位二进制数中为000000。因此AAAA为000000 000000 000000 000000

然后,如果我们使用IAAM执行此操作,则会得到:001000 000000 000000 001100

则该位表示形式是4个数字的VLQ编码版本。我们从左边的块开始,删除符号和延续位,保留这些位。并在连续位为1时继续添加它。

eg. 001000 is (cont)0100(sign)
so cont = 0 (no other block will be added to this number)
sign=0 (its positive)
bits = 0100 --> so it is 4 in decimal

-- note that we only remove sign bit for the first time. so if we had
101000 001000
we would say
0100 (cont=1, sign=0) 01000 (cont=0)
so we would have had +010001000 = 136

当我们继续这样做时,我们将获得这4个数字(连续位应为0恰好是4倍)。

  • AAAA会映射到(0,0,0,0)
  • IAAM将映射到(4,0,0,6)
  • WAAW将映射到(11,0,0,11) ...

现在,这些均代表相对数。所以我们更正了这些:

  • AAAA实际上指向:(0,0,0,0)
  • IAAM实际上指向:(0 + 4,0 + 0,0 + 0,0 + 6)=(4,0,0,6)
  • WAAW实际上指向:(4 + 11,0 + 0,0 + 0,6 + 11)=(15,0,0,17)//我们在IAAAM实际指向的地方添加了它

...

所以数字(n1,n2,n3,n4)代表

  • n1:生成的代码中的列
  • n2:sourceMapping输出的“ sources”数组中的相应源文件索引
  • n3:原始代码中的行号
  • n4:原始代码中的列号

我们已经从一开始就知道这是哪一行。因此,利用上面的信息,我们了解到:

  • AAAA:生成的代码的第2行第1列指向source [0]的第0行第0列
  • IAAM:生成代码的第2行,第4列指向source [0],第0行,第6列
  • WAAW:生成代码的第2行第15列指向source [0]的第0行第17列 ...

关于此的两个很好的资料来源: