为什么最流行的编码算法是刚好带两个符号破坏兼容性的 base64,而不是能够无视大小写的 base36、不带符号的 base62?这两个符号不仅严重影响兼容性使标准码表的 base64 不能直接拼在 url 中,还没有增加多少信息密度

111 天前
 drymonfidelia

base64 的编码结果并不是二进制,码表长度是 2 的整数次方没有任何的加成。

被 base64 坑了好几次,按=截断 key=value 数据的时候忘记指定 maxsplit=1 导致=后面的数据丢掉。

5911 次点击
所在节点    程序员
49 条回复
liuidetmks
111 天前
避免除法,
你有 1G 数据流,直接当做一个整数,那是很麻烦的
而且可以流式处理,不用等到所有数据都接受到了才编码
CEBBCAT
111 天前
菜就多练,URL 传递 Base64 就用 Base64URL ,硬传不就等于自己给自己挖坑吗?用的哪个语言?没有便捷的库?
lisongeee
111 天前
> 被 base64 坑了好几次,按=截断 key=value 数据

看起来你的场景是在反序列化 url string 里的 search 参数,好奇为什么不用标准序列化对象?

https://developer.mozilla.org/en-US/docs/Web/API/URL

另外将 base64 编码到 url search 参数里的时候,也要调用标准序列化方法

此时 base64 里的 = 字符会变成 %3D ,如果按照这个标准序列化,你的分割不会出现错误

我猜测两边都是手动拼接/手动分割字符串去构造参数,而不是去使用标准序列化和反序列化方法

我们这边后端一个系统 解析/构造 url 的时候不按照标准走,产生如 hash 丢失,参数解码错误破坏整个 url

还有 飞书 的网页第三方登录,点击拒绝授权的时候,如果你的参数里面有 url ,url 里面有特殊字符,虽然你的按标准走的,但是煞笔飞书会手动解码两次后拼接,导致破坏整个 url 导致参数丢失

每次跟这些不按标准喜欢自己拼接字符串的煞笔对接都气死我了
adoal
111 天前
手拼 URL 不检查不转换参数偏要怪 base64 使用了不兼容 URL 的字符……那你手拼 SQL 直接传裸参试试。
tool2dx
111 天前
@lisongeee RFC 标准有,就是 https://en.wikipedia.org/wiki/Base64 里的 base64url ,简单来说就是把'+'和'/'变成'-'和'_', 再把尾巴=去掉。

在国外项目挺常见的,比如 lets encrypt acme 协议提交的 url ,就必须这样编码。
lisongeee
111 天前
@tool2dx

你的回复和我的回复没有一点关系,你是不是回复错人了

---

另外 base64 尾部的 = 只是为了让这个 base64 string 的长度是 4 的倍数

而现在的大多数解析器解析时都是支持忽略尾部 = 字符的,所以很多工具生成的 base64 都没有 = 字符
tool2dx
111 天前
@lisongeee 嗯,我只是多一句嘴,回复确实没啥关系。
DOLLOR
111 天前
先不说 base64 ,你拼 URL 的时候不用 encodeURIComponent()再包裹一遍吗?被坑了几次都还没这个意识吗?
FengMubai
111 天前
base16(hex): 变为原来的 2 倍
base32: 1.6 倍
base64: 1.333 倍
base85: 1.25 倍

base85 里有反斜线, base64 已经很折中了
BugCry
111 天前
网站可以发出来看一下吗,我保证不做 sql 注入
drymonfidelia
111 天前
@vvhy
@CEBBCAT
@lisongeee
@adoal
@tool2dx
@DOLLOR
@BugCry 我又没说我在 url 里直接拼 base64 ,是我对接的很多人、接口都在往 url 、cookies 里直接拼接 base64 ,大厂也在这么干。例如你随便打开一个有接入 akamai bot manager 的网站,像 nike.com ,找到 _abck 这个 cookies ,第三段就是直接拼接的 base64
drymonfidelia
111 天前
@drymonfidelia 然后 cookies 就是 key=value 编码的,如果直接按=截断就会出现这个问题
zpfhbyx
111 天前
base64 urlsafe
oamu
111 天前
稍微了解下位运算也不至于说出 “码表长度是 2 的整数次方没有任何的加成。” 这种话。
proxytoworld
111 天前
@drymonfidelia 你没对=做判断吗,=是最后出现的字符,而且最多两个,这分割没啥大问题啊
tool2dx
111 天前
@drymonfidelia 你标题有没写 cookies ,只说了 url 。

cookies 内是允许用=符号的,虽然我也觉得解析起来会很奇怪,但浏览器确实是允许的。
msg7086
111 天前
URL 不适合用 base64 所以有了 base64 的 url-safe 版本。
Cookie 不是问题吧,本来就是按等号分割成两部分,第二部分有没有等号不影响使用。
drymonfidelia
111 天前
@msg7086 URL 一样是用=分为两部分,只是 cookies 分隔符是=和;,URL 是=和&,没有本质区别我就只写了一个
@tool2dx
NoOneNoBody
111 天前
既然都说的二进制,总应该知道 6 个 bit 就是 64 吧? 62 不能完整表示 6 个 bit 啊,36 表示 5 个 bit 又浪费了几个字符
这些编码本来就早于 url 诞生的,你应该问的是为什么 url 标准不考虑兼容 base64

base64 的重要思想是将 bytes 以可视、非控制字符表示,是 bytes 类型转无控制字符的 string 类型的最简单实现,压根就和 url 没什么关系
cheng6563
111 天前
有没有可能就是单纯的 base64 比 url 诞生的早?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1069022

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX