@Lenciel

他的密码原来是...

2014年左右,大叔们往 Github 上丢 BSD3 的源码时,放上了 /etc/passwd 文件,于是诸如 Ken Thompson,Dennis Ritchie,Brian W. Kernighan 这样的老司机就玉体横陈了,只不过关键部位,打了马赛克:

call me by your name

众所周知,打马赛克的 crypt 函数是基于 DES 的,很弱。说众所周知是因为它的作者 Robert Morris 和 Ken Thompson 在 manpage 里面自己就是这么写的:

The DES algorithm itself has a few quirks which make the use of the crypt() interface a very poor choice for anything other than password authentication. If you are planning on using the crypt() interface for a cryptography project, don’t do it: get a good book on encryption and one of the widely available DES libraries.

我猜设计者这么实现是有它的“历史原因”的:那个年代大众能够获取的计算能力还非常弱搞不了什么暴力破解,以及OS的安全机制是分层的(比如这个文件本来要root才能打开看)。现在 crypt 早就是 obsolete 的了,大家至少都用基于 AES 的 mcrypt 或者 ccrypt

总之,现在大家的机器这么猛,只需要用 hashcat 这样的工具,就能很容易看到文件里面大多数人的明文密码了:所以你能想到Brian的密码是 /.,/.,, 么。

但是,这堆人里,Ken爷的密码就没有那么容易看到,一下子成了悬案。当时觉得因为这部分代码就是他写的,知道有多弱鸡,所以设密码的时候用了门槛很高的组合:毕竟弱如 DES ,如果努力混用大写字母和特殊字符,就算上GPU也得搞好几年才能出来的。

结果,今天偶然在订阅里看到一个帖子,上个月一个叫 Nigel Williams 的兄弟用一块 AMD (还能是谁的呢)的 Radeon Vega64 把这个密码给破解了:

call me by your name

所有人看到这邮件的感觉应该都是,原来如此,但 p/q2-q4! ,这密码Ken爷你怎么记住的。

结果有人解读说,这是一种国际象棋记谱子的方法p/q2-q4! 表示了很常用的Queen’s Pawn开局

嗯,Ken爷这样的计算机对弈的先驱,记住这样的密码应该不是难事吧。

他们真有趣,我们要学习。

Blog加速:使用WebP图片格式

这个 Blog 对本座来说,除开记录胡思乱想,最重要的作用就是保持和前端世界一点同步。最近打算在不使用 CDN 的情况下, pagespeed 跑到100分,所以做一些早就想做但是一直没空的改造,排在最前面的就是使用 WebP 格式放正文图片。

什么是WebP

WebP 是 Google 开发的新图像格式,旨在以可接受的视觉质量为无损和有损压缩提供较小的文件大小,Google 报告称自己使用 WebP 代替其他有损压缩方案实现了 30% 至 35% 的流量节省。自问世以来,已经有包括 Netflix、Amazon、Quora、Yahoo、Walmart、Ebay 在内的许多大公司在生产环境中使用 WebP 来降低成本并缩短网页加载时间。

目前它最大的问题是浏览器兼容性,根据 CanIUse.com 可以看到 Chrome 和 Opera 对 WebP 提供原生支持。 Safari、Edge 和 Firefox 已经试用 WebP,但尚未在官方版本中进行使用。

以我最近用过的一张图片为例,使用 WebP 的效果是非常明显的:

Vhost threshold

怎么办

既然不是所有用户的浏览器都支持,那么就得找到办法根据不同的浏览器展示不同的图片。万幸在浏览器和网站建立连接的第一个请求里面,会有一个声明浏览器能力的 Accept Header

于是,由于这个站是用 Nginx 来运行的,要做到这点分三步。

让服务器认识WebP

/etc/nginx/mime.types 里加上:

1
image/webp  webp;

根据访问者的请求头赋值变量

/etc/nginx/nginx.conf里的 http 段落里面加一个:

1
2
3
4
map $http_accept $webp_suffix {
  default   "";
  "~*webp"  ".webp";
}

这里的作用主要是,如果 $http_accept (更多信息可以查看 ngx_http_map_module)代表的访问者的头里面有 webp,那么 $webp_suffix 就赋值为 .webp,否则就是一个空字符串。

定义空字符串这种方法比较“硬编码”,但是这里不用 rewrite 来实现主要是出于性能方面的考虑:nginx的变量是 lazily calculated 的,所以使用这样的方式不会影响其他文件。

根据变量值返回

在 Nginx 的配置文件 server 段落里面加上:

1
2
3
4
5
6
7
# webp extension support if you are converting /uploads images to webp
 location ~* \.(png|jpe?g)$ {
   expires max;
   add_header Vary "Accept-Encoding";
   add_header Cache-Control "public, no-transform";
   try_files $uri$webp_suffix $uri =404;
 }

这里最主要的是 try_files 的部分:

  • 如果有原请求+“.webp"后缀的文件,就使用它返回
  • 如果没有,返回原来请求的文件
  • 如果都没有,返回404

更多 try_files 的用法可以看这里

批量生成WebP文件

重启服务器之后,就可以看到已经工作了。在使用 Chrome 进行访问的时候,WebP 格式的图片会加载。

Vhost threshold

至于如何批量把现有的图片转换成 WebP 格式,有很多工具可以用,需要考虑的是在服务器端完成,还是在本地完成。