SLS 数据加工“数据编码、解码”实践

引文

在数据的生命周期基本可以概括为生成、传输、计算、存储、展示这么几个流程,每个流程可能会重复执行。在完整周期中,为了满足便捷性、安全性、执行效率等各个方面的考量,我们会引入各种各样的编码方式,比如图片的JPEG格式、文本的UTF-8编码、访问网址参数需要URL编码等。
简单来说,计算机所能表达的数据都是以0和1构成的二进制内容,某种数据编码方式就是遵循某个数据使用者都认可的标准或者协议,而协议存在的最根本意义就在于不同的使用者能够的到准确的数据内容。数据的编码和解码过程,就是将满足标准的A的数据转换到B协议的过程。
这里我们对 SLS 数据加工中关于数据编码和解码的场景做一个汇总,主要分为编码与解码、压缩与解压缩、加密与解密、哈希摘要 4 个部分。

数据转换

在编程语言中存在赋值操作,即是将内存中的数据块添加一个名字,方便编程语言中使用。类似的,在 SLS 数据加工中,将数据赋值为字段值可以通过 e_set 函数完成,比如 e_set("field_name", "field_value"),或者 e_set("field_name", v("another_field_name")),这里 v 的作用是提取对应字段的值。

编码、解码

字符串编码

对于开发人员来说,字符串的编码是最常见的编码场景,也是非常让人头疼的问题,ASCII、Unicode、UTF-8、GB232 ,各种各样字符和的编码傻傻分不清楚,动不动就乱码。这里对于字符的编码原理不做细究,针对看一下数据加工提供的能力。

  1. 将字符串编码为二进制数据

原始数据:

content: "SLS 数据加工"

加工规则(为了做展示,这里进一步将二进制数据编码为16进, 下文会进一步讨论):

e_set("i_am_binary", op_add("0x", bin2hex(str_encode(v("content"), "utf8"))))

加工结果,这里 i_am_binary 字段所表示的二进制为 \x22\x53\x4c\x53\x20\xe6\x95\xb0\xe6\x8d\xae\xe5\x8a\xa0\xe5\xb7\xa5

content: "SLS 数据加工"
i_am_binary: 0xe695b0e68daee58aa0e5b7a522
  1. 将二进制数据编码为字符串

原始数据:

i_am_binary: 0xe695b0e68daee58aa0e5b7a522

加工规则,直接对二进制参数做转换

e_set(
    "content",
    str_decode(
        b"\x22\x53\x4c\x53\x20\xe6\x95\xb0\xe6\x8d\xae\xe5\x8a\xa0\xe5\xb7\xa5",
        encoding="utf-8",
    ),
)

加工结果:

content: "SLS 数据加工

Hex 格式

上文所说,计算机所表示的数据是二进制,也就是说数据中有很多内容是用作特殊功能的,这部分内容没办法直接做展示,但是我们在传输过程中很有可能需要做临时展示,这时就可以将数据内容转换为16进制字符串。
将二进制数据转为hex字符串,上文【字符串编码】部分已经有样例.

Base64 格式

上文所述,可以将不可见内容编码为 hex 格式,同样的能力,Base64 则可以实现更少的编后大小,提高效率。

  1. 将字符串编码为Base64数据

原始数据:

content: "SLS 数据加工"

加工规则:

e_set("i_am_base64", base64_encoding(v("content")))

加工结果:

content: "SLS 数据加工"
i_am_base64: IlNMUyDmlbDmja7liqDlt6Ui
  1. 将Base64数据解码为字符串数据

原始数据:

i_am_base64: IlNMUyDmlbDmja7liqDlt6Ui

加工规则:

e_set("content", base64_decoding(v("i_am_base64")))

加工结果:

content: "SLS 数据加工"
i_am_base64: IlNMUyDmlbDmja7liqDlt6Ui

HTML 格式

  1. 将原始数据编码为符合 html 标准(转义)的字符串

原始数据:

str : <img src="test.jpg" alt="" width="300" height="194" />

加工规则:

e_set("i_am_base64", base64_encoding(v("content")))

加工结果:

str:<img src="test.jpg" alt="" width="300" height="194" />
str_html_en: "<img src="test.jpg" alt="" width="300" height="194" />"
  1. 将 html 转移后的内容,转为原始数据
  2. 将原始数据编码为符合html标准(转义)的字符串

原始数据:

str_html_en: "<img src="test.jpg" alt="" width="300" height="194" />"

加工规则:

e_set("str", html_decoding(v("str_html_en")))

加工结果:

str: <img src="test.jpg" alt="" width="300" height="194" />
str_html_en: "<img src="test.jpg" alt="" width="300" height="194" />"

URL 格式

  1. 将原始数据编码为符合 url 标准(转义)的字符串

原始数据:

query: "x=0,y=1,z=2"

加工规则:

e_set("i_am_base64", base64_encoding(v("content")))

加工结果:

query: "x=0,y=1,z=2"
query_encoded: "x%3D0%2Cy%3D1%2Cz%3D2"
  1. 将 url 转移后的内容,转为原始数据

原始数据:

query_encoded: "x%3D0%2Cy%3D1%2Cz%3D2"

加工规则:

e_set("query", url_decoding(v("query_encoded")))

加工结果:

query: "x=0,y=1,z=2"
query_encoded: "x%3D0%2Cy%3D1%2Cz%3D2"

压缩、解压缩

Gzip 压缩库

Deflate 压缩算法应用非常广泛,gzip 则是封装了 deflate 算法,添加了协议头和协议尾,方便使用。

  1. 将数据做压缩,并输出压缩后的 base64 编码

原始数据:

content: "I always look forward to my holidays whether I travel or stay at home."

加工规则:

e_set("gzip_compress", gzip_compress(v("content"), to_format="base64"))

加工结果:

gzip_compress: "H4sIAOCOyGEC/xXK0QmAMAwFwFXeBO7RMQKNREx5kAZDtle/7wbES3rDyRsnoyQmklgNo1/ztzJN08BAhjzqYGCnNCS/tPR4AcgrnWVGAAAA"
content: "I always look forward to my holidays whether I travel or stay at home."
  1. 将压缩数据(base64 编码)解压缩

原始数据:

content: "H4sIAOCOyGEC/xXK0QmAMAwFwFXeBO7RMQKNREx5kAZDtle/7wbES3rDyRsnoyQmklgNo1/ztzJN08BAhjzqYGCnNCS/tPR4AcgrnWVGAAAA"

加工规则:

e_set("gzip_decompress", gzip_decompress(v("content"), from_format="base64"))

加工结果:

content: "H4sIAOCOyGEC/xXK0QmAMAwFwFXeBO7RMQKNREx5kAZDtle/7wbES3rDyRsnoyQmklgNo1/ztzJN08BAhjzqYGCnNCS/tPR4AcgrnWVGAAAA"
gzip_decompress: "I always look forward to my holidays whether I travel or stay at home."

Zlib 压缩库

Zlib 同样是封装了 deflate 算法,它兼容了 gzip 的封装头和尾。

  1. 将数据做压缩,并输出压缩后的 base64 编码

原始数据:

content: "I always look forward to my holidays whether I travel or stay at home."

加工规则:

e_set("zlib_compress", zlib_compress(v("content"), to_format="base64"))

加工结果:

zlib_compress: "eJwVytEJgDAMBcBV3gTu0TECjURMeZAGQ7ZXv+8GxEt6w8kbJ6MkJpJYDaNf87cyTdPAQIY86mBgpzQkv7T0eAGNshln"
content: "I always look forward to my holidays whether I travel or stay at home."
  1. 将压缩数据(base64 编码)解压缩

原始数据:

content: "eJwVytEJgDAMBcBV3gTu0TECjURMeZAGQ7ZXv+8GxEt6w8kbJ6MkJpJYDaNf87cyTdPAQIY86mBgpzQkv7T0eAGNshln"

加工规则:

e_set("zlib_decompress", zlib_decompress(v("content"), from_format="base64"))

加工结果:

content: "eJwVytEJgDAMBcBV3gTu0TECjURMeZAGQ7ZXv+8GxEt6w8kbJ6MkJpJYDaNf87cyTdPAQIY86mBgpzQkv7T0eAGNshln"
zlib_decompress: "I always look forward to my holidays whether I travel or stay at home."

加密、解密

AES 加密算法

数据加密是数据安全最基本的保障,AES加密算法应该是作为目前对称加密算法的标准(弥补了DES算法的强度不足),其实现包含了多种数据分组模式,比如 EBC、CBC等等。

  1. 将数据做加密,并输出压缩后的 base64 编码

原始数据:

content: "I always look forward to my holidays whether I travel or stay at home."

加工规则:

e_set(
    "aes_encrypt",
    aes_encrypt(
        v("content"),
        "this is my key..",
        iv=b"xxywosjdapdiawdk",
        output_format="base64",
    ),
)

加工结果:

aes_encrypt: "/3mAdvqWORQkPKgfMvW/IkGBwMRvJSI8Qkyqkr0RJWuRRx8s//qgIq3PMDe6Y/p4Au/sXpe45Bjx0I8fENAgMA1Z9WfG4kIWK5TOShJZYMk="
content: "I always look forward to my holidays whether I travel or stay at home."
  1. 将加密后的数据(base64 编码)解压缩

原始数据:

content: "/3mAdvqWORQkPKgfMvW/IkGBwMRvJSI8Qkyqkr0RJWuRRx8s//qgIq3PMDe6Y/p4Au/sXpe45Bjx0I8fENAgMA1Z9WfG4kIWK5TOShJZYMk="

加工规则:

e_set(
    "aes_decrypt",
    aes_decrypt(
        v("content"), 
        "this is my key..", 
        iv=b"xxywosjdapdiawdk", 
        input_format="base64",
    ),
)

加工结果:

aes_decrypt: "I always look forward to my holidays whether I travel or stay at home."
content: "/3mAdvqWORQkPKgfMvW/IkGBwMRvJSI8Qkyqkr0RJWuRRx8s//qgIq3PMDe6Y/p4Au/sXpe45Bjx0I8fENAgMA1Z9WfG4kIWK5TOShJZYMk="

哈希摘要

MD5 哈希

数据摘要(哈希)一般用于数据正确性验证(防篡改),md5 是较为经典的哈希算法,在哈希均匀程度上表现优异。
将数据做 md5 哈希:
原始数据:

content: "I always look forward to my holidays whether I travel or stay at home."

加工规则:

e_set("md5_hash", md5_encoding(v("content"), format="hex"))

加工结果:

content: "I always look forward to my holidays whether I travel or stay at home."
md5_hash: 30a07986f2d3e6a3692c1cb89e222b69

SHA1 哈希

SHA1 族哈希函数相对于 md5 有更强的反碰撞能力(更安全),包括 SHA256、SHA384、SHA224、SHA512。
将数据做 sha1 哈希:
原始数据:

content: "I always look forward to my holidays whether I travel or stay at home."

加工规则:

e_set("sha1_hash", sha1_encoding(v("content"), format="sha512"))

加工结果:

content: "I always look forward to my holidays whether I travel or stay at home."
sha1_hash: f3c65fa56113673674e0e630cdff1f365f3e64904a31b0fdae865c7b425178f33f5387b657aa520813be64cb4c2afede5bc39a59276fff29d211384dfa68dd91

总结

以上列出的是的数据编码方式的转化实践,数据的编码和解码还包含更加高级的应用,比如 json、csv、xml、yaml 等,SLS 数据加工也有相应的解决方案,这里先不做讨论。
下图是 SLS 团队的技术博客,我们会不定期推出技术文章分享和产品更新介绍,欢迎大家订阅,有任何问题也欢迎与我们反馈。
SLS 数据加工“数据编码、解码”实践

上一篇:《Linux From Scratch》第三部分:构建LFS系统 第六章:安装基本的系统软件- 6.5. 创建目录


下一篇:《Linux From Scratch》第三部分:构建LFS系统 第六章:安装基本的系统软件- 6.4. 进入 Chroot 环境