Hypercube's Channel
89 subscribers
40 photos
3 videos
2 files
37 links
随便搞的一个 channel,还不知道会变成什么样

可以使用 Telegram 的转发功能转发消息
Download Telegram
尝试录屏并剪辑了 Advent of Code 中两道题的做题过程,之后可能还会发更多:

day 18: https://youtu.be/i4EB36076Pw
day 19: https://youtu.be/toJVMxv-AuE

我以前思考过如果直播或录制我写代码的过程,有没有可能别人会想看。我一直挺怀疑的,不过前两天和 @zzh1996 聊天时他提到一些细节做法可能有参考的价值,例如:
- 使用 copilot 的频率
- 使用自动补全的频率
- 怎么快速看特定函数的文档
- 边写边编译检查还是最后统一解决编译报错

我觉得有道理,正好 Advent of Code 每道题比较简单、互相独立,更适合做成视频,就用它试试。

我以为别人不会对我的城市天际线存档感兴趣,因为只是我按自己的想法和目标玩的,对别人没啥用。但居然有人收藏下载,所以我又知道什么呢😂说不定这种录屏也会对别人有用吧。
我每天吃饭的时候会在直播平台上找一个循环连播电视剧的频道看,但最近发现某个这样的频道有一个小问题:它循环长度约等于 24 小时,导致我总是看相同的一些集。我在想如果我做这样循环连播的频道,应该把循环长度控制在多少最合适呢?

我的第一反应是应该和 24 互素,但时间是连续的,并不是以小时为最小单位离散的。第二反应是应该令最大公因数最小,但这意味着任何无理数循环长度都一样最优,显然不是我想找的答案。我其实希望每天看到的位置和前几天看过的都相隔足够远。

我认为答案应该是黄金分割比,令循环长度为 24 小时的 0.382、0.618、1.618 等倍数。这正好和另一个我思考过的问题相同:在色调的一圈 360 度上选择颜色,该怎么选出 n 个颜色,让它们两两都相隔尽量远?当 n 已知时 n 等分即可。当 n 未知时(不断要求再增加一个颜色),如果 m 等分了前 m 个颜色,第 m+1 个颜色只能放在某两个颜色中间,离两侧都太近。按照黄金分割比,总把第 i 个颜色选在 i*0.618*360 度处,按我的理解是最优的。植物的叶片也近似是按这个规则生长的,可以在总数量未知的情况下尽量均匀分布。

参考: https://en.wikipedia.org/wiki/Golden_angle
Hackergame 将选手 ID 加上电子签名称为 token,用于题目认证选手。考虑到题目中的认证逻辑可以被选手看到,但不应该能生成他人的 token,所以不能用 HMAC。现有做法是:将选手 ID 转为字符串,与椭圆曲线签名再 base64 的结果拼接,例如“42:MEUCIQCE……”。题目需要:
A1. 将收到的 token 按冒号切开。
A2. 将右侧 base64 解码后验证是否为左侧的合法签名。
A3. 用整个 token 或只用左侧隔离不同选手的环境,以及限制资源用量。
A4. 用整个 token(加盐)哈希作为题目答案。不能只用左侧是因为不应该能生成他人的答案。

关键问题是一个选手能否对应多个不同但都合法的右侧部分。如果能的话,A3 必须只用左侧,不能用整个 token。A4 一个选手会对应多个不同的题目答案,处理起来很棘手。如果不能的话就全简单了,A3 和 A4 都可以直接用整个 token。

想确保一个选手只能对应唯一 token 的话,需要注意以下细节:
B1. 按冒号切开的这一步不要写出漏洞,例如不要接受“42:garbage:MEUCIQCE……”。
B2. 椭圆曲线签名可以被人为变换产生另一个不同但也能通过数学验证的签名(malleability),解决这个漏洞的标准做法是规定只有某一个合法,另一个非法。
B3. 很多 base64 库会把不同输入对应到相同输出,例如“A/B=”改成“A/ B=”、“A/B”、“A_B”、“A/C=”可能都可以得到相同输出,应当只允许标准形式。Python 所有版本的 base64 库都有此问题。
B4. 尤其不要不验证就直接相信左侧的 ID。

libsodium 可以解决以上所有问题,它不像 OpenSSL 等库提供底层算法,而是提供绝大多数程序实际需要的高层功能,考虑了各种细节。crypto_sign 函数把 ID 变成 token,crypto_sign_open 函数变回来。
C1. 不用自己切分 token 了。
C2. 它生成的 token 格式不直观,一定程度上避免绕过 crypto_sign_open 直接看 ID。
C3. crypto_sign_open 能确保一个选手对应唯一 token,遇到其他形式或验证失败都不会返回 ID。

延伸阅读: https://hdevalence.ca/blog/2020-10-04-its-25519am
http://tom7.org/abc/
非常有趣的一篇 paper(和一个程序)。这个作者的其他项目,以及 SIGBOVIK 的其他 paper 我也都很喜欢。
前几天我在想,怎样能设计一个游戏,它的核心玩法涉及 AI 独特的能力(也就是不用 AI 就做不出这样的游戏),并且不是对话式的(因为对话式的 AI 相关游戏已经太多了)。

我做了一个这样的 demo,从“金木水火土”5 个汉字开始,每一步玩家可以点击两个字来组合,AI 决定组合得到什么,游戏目标是组合出某个特定的字。但是玩了玩感觉并不是很有趣,尤其是绝大多数心里想的目标实际上非常难组合出来。我尝试了很久合成“新年快乐”四个字中的任何一个,这几个字的含义都有点抽象,很难通过具体的概念得到。

今天在 Hacker News 看到简直一模一样的想法被别人做了😂其实还是有一定可玩性的,不过确实和我当时遇到的困难一模一样,就是想合成特定目标的话非常难,导致只能是个随便玩玩的游戏,没法引入胜利条件或者分数的概念。

(建议手机上尝试,电脑版的 UI 逻辑不好用。)
在看游戏音乐拍号(time signature)相关视频,评论里有人提到 Splatoon 的音乐 Frothy Waters 每小节增加一拍,依次用了 10/8、11/8、12/8 直到 25/8 的拍号。它就是 Splatoon 3 正常打工过程的背景音乐,我听了那么多遍居然都没注意到这个特点🌚

https://youtu.be/jcxsYaWoIkQ?t=1082
没想到不同银行在存款证明方面的逻辑有这么大差异,我目前试出来的信息:
- 招商银行:可开非冻结或冻结的,会显示开户日期,可以任意输入更小的金额数字
- 中国银行:只能开冻结的,可以冻 1 天但不能不冻
- 中国建设银行:可开非冻结或冻结的(他们称为时点和时段),不显示开户日期,不能自定义金额,只能是当前实际余额
不同云服务商的几台机器之间有安全通信的需求的话(例如需要调用 HTTP API 或连接数据库),可以选择 VPN 或者 TLS。如果自己维护一个 CA,为所有机器正确配置 server certificate 和 client certificate 的话,是可以达到与 VPN 相似的保护效果的。

但是由于种种原因,TLS 有一些设计并不令我满意,效果上总是比 VPN 差那么一点。例如:端口号是公开的,别人一扫就知道你在运行什么服务,改用随机端口的话不太方便,并且仍然可以扫出一些信息。验证 client certificate 之前就会发送 server certificate,这里面可以泄露不少信息,包括 hostname、证书签发时间、CA 的名字等,可以用于猜测这台机器的拥有者和功能。SNI 目前仍然是没加密的。用 VPN 的话是没有这些信息泄露的。

但 VPN 也有自己的问题,配置起来更麻烦一些,不适合增量式地为每个应用配置,需要提前决定好怎么把所有机器组网,想临时给别人一个权限时,给对方签一张 client certificate 也更轻量级。

如果想要一种可以为各个应用按需启用的、可以灵活配置权限规则的方案,似乎还是更像 TLS 一点。它要是把更多步骤挪到检查客户端证书之后再做,并且都加密传输,就好了。
遇到了一个神奇妙妙 bug,我使用某系统时总是有概率登录失败,需要重试才能成功。而且最近几个月以来失败概率越来越高,到了难以忍受的程度,常常需要重试两三次才能成功。但别人都没遇到同样的问题。

今天在 @taoky42 认真调查之后终于搞明白了,问题在于登录时在数据库中查询我的本月用量花费的时间超过一秒。数据库表结构为 使用记录(时间, 用户, 用量),时间列和用户列分别有单列索引,查询语句为 select sum(用量) from 使用记录 where 用户 = ... and UNIX_TIMESTAMP(时间) > ...。

我看到这个查询的第一反应是,这肯定用时间索引,然后行数很少,应该不会慢,就算慢也不可能只有我一个人慢,应该是大家一样慢。但是,注意以下两种写法的区别:

1. UNIX_TIMESTAMP(时间) > ...
2. 时间 > FROM_UNIXTIME(...)

1 运行花费 1.37 秒,2 运行花费 0.05 秒。1 用不上时间索引,只能用用户索引,导致行数多了不少,并且每行还有函数调用开销。
SQLite 支持一些处理 JSON 的函数,可以直接对 JSON 格式的列进行查询和建立索引,看似很方便,但要当心:

1. json('{"a/b": 1}') != json('{"a\/b": 1}')
虽然在 JSON 的意义上两个 object 是一样的,但 SQLite 认为是不等的。

2. json_extract('{"a\/b": 1}', '$.a/b') is null
类似地,json_extract('{"\u0031":1}', '$.1') is null
类似地,json_extract('{"\u6211":1}', '$.我') is null
这个问题只在老版本的 SQLite 上存在,最新版本已经修复了。

感觉很坑,因为很多时候我是没法控制我用的 JSON 库怎么 escape 各种字符的,例如 / 这个字符其实不必 escape,但有的库会把它 escape 成 \/,进了 SQLite 后就会出现匹配不到 key 的问题。
微信备份/迁移聊天记录时会丢失和公众号的对话记录,包括公众号推送的文章和消息记录,以及自己打字和公众号对话的记录。望周知。

(上一条消息搞错了,删了重发)
怎么避免“毕业论文10.pdf”排序时排在“毕业论文1.pdf”和“毕业论文2.pdf”之间?一个非常简单并且足够好的做法就是把连起来的数字看作一个整体,["毕业论文", 10, ".pdf"] > ["毕业论文", 2, ".pdf"]。这样遇到“毕业论文13送审版.pdf”、“毕业论文13送审版2.pdf”等更复杂的情况时也会正好产生好的结果。

我之前一直觉得这个问题就算是已经解决得很好了,今天给 @zzh1996 讲这个算法时,他说“听起来十六进制的文件名会完全乱掉”,我才意识到有这个坑😂我好像从来没有在 Windows 文件管理器等程序中打开过包含很多十六进制文件名的目录。

那 Windows 是怎么解决的呢?刚刚调查了一下,Windows 还真就没解决这个问题,我想了想也没想到好的方法。
IEEE 754 认为二进制规约浮点数应该视为 (-1)^s * m * 2^e,其中 s 是符号位,m 是一个二进制数,其整数部分总是为 1,小数部分每一位都是 0 或 1,e 是指数。

也就是说,一般来说系数 m 应满足 1 <= m < 2,在这个形式下才按照 m * 2^e 这个公式定义指数 e。提到指数的最小值和最大值时也都是按这个标准理解的,例如规定双精度浮点数的指数最大值是 1023,所以 1.999 * 2^1023 能表示,2 * 2^1023 就超出范围了。

但 C 和 Python 提供的提取浮点数指数部分的函数 frexp 居然用的不是这个定义。它总是把系数放到 0.5 <= m < 1 这个范围内,并相应返回指数,导致一般来说它返回的指数比 IEEE 754 中常说的那个指数概念大 1。它有可能返回的最大指数是 1024,不是 1023。

当然这里怎么规定都是可以的,但采用和 IEEE 754 不同的规定会导致 emin emax 对不上,感觉平添不少混乱啊。
我做实验时常遇到这个需求:在对数意义下均匀地测试一个变量的一系列取值,例如每秒 10 个请求、100 个请求、1000 个请求时系统性能,或是 4KiB、8KiB、16KiB 等不同数据量的处理性能。

每次乘以 10 或乘以 2 都比较简单,但是如果希望乘以更小的数,还希望序列中的数字有效位数较少,对人来说看起来方便,就有点难了。例如每次简单地乘以 1.1 会得到 1.21、1.331、1.4641、1.61051。

于是我常在实验脚本中手写:[10, 13, 17, 20, 25, 30, 40, 50, 60, 80, 100, 130, 170, …],相对来说比较好读,对数意义下切分也比较均匀。(不需要完美均匀,只是越不均匀的话实验效率越低,会有一些区间实验太多,另一些区间实验不足。)

今天才知道这个问题叫 https://en.wikipedia.org/wiki/Preferred_number ,一些例子:

1-2-5:1, 2, 5, 10
R5:10, 16, 25, 40, 63, 100
R10:100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000
E3:10, 22, 47, 100
E6:10, 15, 22, 33, 47, 68, 100
E12:10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82, 100
E24:10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91, 100

E 系列的数还有一个好处,E6、E12、E24 分别近似每步加 50%、20%、10%,步长比较“整”。
把我一直在用的 bashrc prompt 作为单独的项目开源了😃并给代码加了详细的注释以便修改,欢迎取用。

https://github.com/SmartHypercube/fancy-prompt
这么多网站用 https://github.com/bilibili/flv.js 播放视频,yt-dlp 和 youtube-dl 怎么都没人做过下载 flv.js 中的视频的功能呢?网上一个相关内容都搜不到。