知乎“分享”功能可能正危及你的隐私

如果你和我一样是知乎和 QQ 的深度用户,你可能对这样的消息格式很熟悉:

一条知乎的分享消息

这是从知乎安卓客户端(因为我是安卓用户,所以本文只讨论安卓客户端的问题,iOS 不清楚,可能一样可能不一样)分享到 QQ 的文案格式。让我们仔细看看这个链接:

https://www.zhihu.com/question/61427877/answer/361977341?utm_source=qq&utm_medium=social&utm_member=YzA1N2VkNTNiYTMyMmMwZDdiODYxYmI0NDRiOWZlYTY%3D%0A

一个分享链接

紫红色的部分就是打开这个页面所需要的链接。里面有两个数字,分别代表问题、回答,这样,这个链接就会打开一个回答的页面。这很好,完全没有什么问题。

接下来,绿色的部分:utm_source=qq。到这里,事情变得很微妙。这表示这个链接是通过 QQ 分享出来的。蓝色的部分:utm_medium=social,这表示这个链接是通过社交平台分享出来的。你可以试试把这两个参数删掉,这并不影响你打开这个回答页面。

最重要的问题在黄色的部分:utm_member=Yz.....%3D%0A。你会发现这个部分很长,而且看上去似乎没有什么意义。真的如此吗?我将简单的演示如何通过这个字符串来获取你的知乎个人页地址。

做一些转换

把这串乱码做 URL 解码,再做 base64 解码。此时,它变成了一串 16 进制字符串——好的,还是乱码。但这串乱码已经有用了,打开 https://zhihu.com/people/c057ed53ba322c0d7b861bb444b9fea6 ,你会看到,它跳转到了分享人的个人页。

感谢兮嘉的出演

这样就完成了一个“从分享链接找到分享人的知乎帐号”的过程。这其实很严重——如果你把链接分享到一个群里,那么当群友打开这个链接时,知乎就知道了你和他们是群友;群友也知道了你的知乎帐号。这是十分明显的隐私信息泄漏。

为了讨论隐私泄漏的问题,我们先来聊一聊追踪是如何实现的。如果你已经了解了 utm 追踪,你可以跳到第二节“这有什么问题?”继续阅读。

追踪如何实现?

链接

万维网用户对“链接”都非常熟悉。简而言之,万维网通过链接联系在一起,通过链接来在不同网站、不同应用之间导航。

一个典型的链接,如同一开始我们提到的那个,是由协议、主机、路径、参数和一些其它部分构成。其中,协议和主机用来确定请求该如何、发送到哪个服务器,而路径和参数则是直接发往服务器,由服务器用于决定展示什么内容。

在分享时,知乎,或者其它别的什么 App,大致都会将当前页面的内容生成一个链接,然后再将链接分享到其它 App 中。

utm 参数

上文我们提到了,参数是直接发往服务器的,而分享的时候可以自定义参数,意味着我们可以通过在链接中加入一些特殊的参数。这些特殊的参数静静的躺在链接里,等待别人点击——而一旦被别人(比如你分享的好友)点击,这些参数就将发往服务器,服务器就知道:哦,这个用户的请求有这些参数,意味着他是从分享链接点击过来的。

而 utm (Urchin Tracking Module)参数是业界通用的、用于处理追踪的参数。通常而言,这些参数并不影响你打开的页面是什么样的(对用户无感知),只是用来统计和追踪。这些参数通常以 utm_ 开头。(扩展阅读:https://en.wikipedia.org/wiki/UTM_parameters

就像知乎做的那样,分享的时候增加了 utm_source=qq 这个参数,其它用户点击的时候,这个参数会被发送到知乎服务器上。这样,知乎的服务器就知道了,你的好友是通过 qq 分享的链接访问的知乎。

追踪的积极意义

如果你理解了前面我所说的内容,你很容易想到为什么大家会热衷于使用追踪技术。产品经理想了解从哪个渠道的分享到达率最高、哪个渠道的转化最厉害,或者可能根据来源渠道给予各种奇奇怪怪的针对性优化(或者负优化……)。甚至说,有一定规模并建立起一定的监控机制之后,如果某个渠道出现了问题,也可以迅速发现。

这有什么问题?

如果说追踪对用户没有感知,并且又有那么多好处的话,为什么我要说知乎正在危及你的隐私呢?事实上,由于链接参数的可见性(对第三方平台、浏览器等工具是可见的),这些参数可能被泄漏给第三方。此外,对第一方(应用开发者,比如知乎)而言,许多所有用户操作都属于用户的个人隐私,需要对用户显式说明。

我将在这里简单的说明几个较为明显、容易想到的问题。这些问题并不一定实际存在——我也不知道他们是不是存在,我只在此提出:这些技术是完全可行的,并且知乎也可以简单的避免这些问题。

跨平台的用户追踪

对于每个用户而言,不管你分享多少次,只要你不退出或者更换帐号,utm_member 是不会变化的。这可以被唯一标识用户,我们称之为“知乎用户标识”——当我们看到这个用户标识,就知道它是你。虽然这个链接是 https 的(这样运营商和中间服务器不会看到链接),但除了你和知乎,还有别人可以获取这个链接。

比如你分享到 QQ 上,那么 QQ 就可以知道你的知乎用户标识;你把链接复制到微博,那么微博也知道了你的知乎用户标识;你用浏览器打开,浏览器也知道了你的知乎用户标识。第三方平台完全可以把你在他们平台上的帐号和你的知乎用户标识关联起来,实现跨平台追踪。

可被任何人识别的用户标识符

文章的开篇部分我简要展示了如何从分享链接中获取你在知乎的用户信息。这事实上没有任何技术门槛,任何人都能进行尝试(如果你对技术一无所知,你可以搜索“在线 base64 解码”、“在线 URL 解码”,能搜索到很多在线工具代劳)。假设你在知乎上是超级大V,但身边的人都不知道、你也不想让他们知道。但现在,只要你通过安卓知乎客户端从 QQ 上分享任何内容给你的朋友,大家都知道你就是知乎大V了……

应该怎么办?

相信你已经理解了问题是如何存在的(如果没有理解那就算了……)。那么如何避免这种隐私问题呢?这里我也从用户和运营方(知乎)的两个方面来思考应当如何处理。

用户怎么办

对用户而言,移动端事实上缺乏这类隐私防范的工具。就当前这个事件来看,我发现通过“复制链接”的方法可以获得相对干净的链接,从而摆脱 utm 的追踪。

在桌面浏览器上,我推荐有些隐私洁癖的朋友使用 Neat URL 这个扩展。它可以移除很多无用的 URL 参数,并且有丰富的自定义功能。(利益相关:我是一个 Firefox 用户,我也推荐每个人使用 Firefox,所以不知道 Chrome 下应该怎么办~)

知乎怎么办

知乎应当从整体考虑放弃追踪特定用户的分享行为。如果你非要那么做,至少请:

  • utm_member 字段每次分享都不一样(避免追踪特定用户)
  • utm_member 字段无法被第三方轻易反解出用户唯一标识

举个我认为比较好的做法:在客户端随机生成一个唯一字符串,将该字符串发送到服务器上,让用户与其关联。每隔一段时间(比如 4 小时)重新生成该字符串。

总结和反思

事实上在发现这个问题之后,我有和一些朋友描述我的发现,并且也试图向知乎反馈该事件,但并未得到什么响应。我想,大概从知乎到用户,所有人都不太理解这为什么对隐私有所伤害。

当然,知乎和国内大部分 App 一样,在隐私方面的问题远不止我提及的这一点,只是这一点非常容易验证而又十分明显,才这样公开的提出来。知乎在国内的移动市场上算是比较有情怀的(起码以前这样……),也希望知乎能够有足够的内部力量推动关注这些事情。

国内在隐私方面的关注实在是太少,而又很难有合适的渠道来了解、学习这些和自己生活息息相关的事情。这篇文章或许有不少片面或者理解不到位的地方,也请各位指正。

Safari 下同页面创建的视频超过 16 个则无法播放

最近在做一些视频相关的东西。在 Safari 下发现这样一个问题:<video> 标签创建多了,会导致同一个页面内后续的视频都无法播放。不管是 iOS 的 Safari,还是 macOS 下的,都存在同样的问题。尤其是 iOS 下,超过 16 个的视频几乎必定无法播放;效果就是显示一个播放按钮并且有一条斜线。

无法播放的视频截图

通过 video.error来检查最后的错误,得到的是 MEDIA_ERR_DECODE;同时,video.play() 方法会 reject 一个 AbortError。在 Google 检索了很久也没有得到有用的信息。

为了演示这个 bug,一个简单的示例的源码被我放在了 gist 上。你可以通过在 Safari 上打开 RawGit 提供的链接 来测试这个 bug。你只需要点击“测试”,并在视频开始播放后再次点击“测试”,如此循环 16 次,便能得到和我上一张图片一样的结果。

示例的代码如此简单,以至于我认为这个 bug 是几乎不可能发生的;它仅仅是调整了一个 DOM 的 innerHTML 来创建一个 video 元素(事实上无论通过何种方法创建,都会有这个问题;playsinline 属性似乎是必要的),然后再删除它,循环 16 次而已。

hello.innerHTML = '';
var src = 'https://cdn.rawgit.com/mediaelement/mediaelement-files/4d21a042/big_buck_bunny.mp4';
hello.innerHTML = '<video id="video" webkit-playsinline playsinline controls src="' + src + '">';
setTimeout(function () {
    document.getElementById('video').play();
}, 500);

目前,我没有发现任何能够解决这个 bug 的方法。可能唯一的办法就是,播放 15 个视频之后,刷新一下整个页面吧。

为熊猫 TV 直播生成带弹幕的录播视频

最近在沉迷谜之声直播。由于有时候下班比较晚,赶不上开播,又偶尔对直播游戏感兴趣的,就会跑去找录播来看。这个主播十分好心,会在贴吧里上传自己的录播视频。然而由于主播自己的录播视频采用 obs 串流的同时录制,对弹幕肯定是无能为力的,于是就想着能不能通过什么办法把弹幕加上去。所幸,办法还是有的。

现在熊猫直播全站 https 后,弹幕数据都是走的 websocket 了,通过 Fiddler 之类的抓包工具可以轻松抓到。不过,知乎上有一篇详细的回答说明老版本弹幕格式,也有一些现成的项目用来解析弹幕,所以这里就不关注弹幕数据格式了。总而言之,我把这些东西封装成了一个 npm 库 pandan,可以通过 node.js 简单的获取一个房间的实时弹幕了。比如:

let room = new (require('pandan').Room)(426346)
room.on('room-danmaku', function ({data}) {
  console.log(`${data.from.nickName}: ${data.content}`)
})
room.join()

有了弹幕数据自然就好办多了。从抓到的数据包来看,有主播开播、下播事件,送礼、送竹子等事件,完全足够我生成弹幕了。通过一段小脚本,可以把弹幕格式转换成下面这个样子的 xml:

...
<d p="1830.6300048828,1,25,16777215,1415241251,0,Da8b0a0d,668464499">再见了我的青春</d>
<d p="1477.6800537109,1,25,52479,1415241254,0,35b92ad0,668464527">虐啊</d>
...

脚本比较丑,就不贴了,相关参数的解析可以看这篇文章。这里有个小问题,由于直播通常有几秒钟的 buffer,所以弹幕整个时效性会稍微延后一些。这个问题在你观看直播的时候不容易发现(因为大家都有延迟),但生成录播之后弹幕会很明显的延后。当然,解决起来也十分简单,将弹幕时间轴往前平移几秒钟就可以了。

然后祭出大杀器:danmaku2ass,一个能将弹幕转换成 ass 字幕的工具。执行类似这样的命令:

python3 danmaku2ass/danmaku2ass.py -o 2017-07-17-1942-09.ass -s 1152x648 -fn "Microsoft YaHei" -fs 30 -a 0.8 -dm 7 2017-07-17-1942-09.xml

就能生成 ass 字幕了。使用任何带字幕功能的播放器,都可以播放啦~看个例子:

example image

当然,并不是所有主播都会自己上传录播视频。如果你刚好也有这种需求,可以尝试在连接弹幕服务器之后,获取开播事件,并在开播之后通过 you-get 来获取直播录像。

2016: 我的浏览器 A – Z

A: https://aoishi.[REMOVED] 自己服务器的管理面板
B: http://bbs.i-cassell-you.com/forum.php 还是卡院
C: http://civitas.soobb.com/ 多少年没上了……
D: https://www.dnspod.cn/ DNSPod 有几个域名在上面
E: http://easy-admin.[REMOVED] ???已经是我记不起来的东西了
F: http://fiddle.jshell.net/ 呃……其实我用得不是很多
G: https://gitlab.com/ Ainou 的代码托管在那,所以经常去
H: http://hicivitas.com/ 以前兼职公司的官网
I: http://www.ip138.com/ …………大概是经常看自己 ip
J: http://jd.com/ 已经不怎么上淘宝了,狗东比较舒服
K: http://kuler.adobe.com/ 一个配色工具,可能是因为在收藏夹吧,平时不怎么用
L: http://logcg.com/ 这是谁的博客啊……完全不记得访问过了
M: https://mp.weixin.qq.com/ 微信公众平台……嗯最近可能是上得比较多
N: http://notes.jetienne.com/ 这又是谁的博客了……不记得了
O: http://openshift.redhat.com/ 我感觉今年我应该没上过
P: http://piao-tech.blogspot.com/ 怎么越来越离谱了
Q: http://qzone.qq.com/ ……啥。。
R: http://redis.io/ 嗯……倒是经常去查文档
S: https://suiyu.xyz/ 偶尔会写日记
T: http://tower.im/ 好用的团队协作工具呢……不过现在也不怎么用了
U: http://upyun.com/ 偶尔会上去配一下 CDN
V: https://v2ex.com/ 毫无悬念
W: http://weibo.com/ 其实我最近比较少上了……
X: http://xiumima.com/ 呃……社工库么
Y: http://yeah.net/ 偶尔会上网易邮箱看看
Z: https://zhihu.com/ 知乎倒是常去看的

总之,通过浏览器,可以看出一个趋势:我使用浏览器浏览不同的 web 网站的时间越来越少了——大部分网站我根本想不起来。而更多的时间,可能花在了刷手机上。移动互联网近年来确实是势不可挡,我也不得不沦陷了。

唯一不变的,大概是 Web 的信仰——以及,今年我还在坚持使用 Firefox 浏览大部分网页。

Tiny Tiny RSS 推送到 kindle

前方高能预警:以下内容本人仅照原样提供,不对其有任何支持!伸手党速速退散,折腾指数五颗星!

前方预警:如果你没有 kindle 或者不打算用 kindle 看 RSS,以下内容对你而言并无作用。

很久以前折腾了一个 Calibre 的自定义脚本,用这个脚本可以将 tiny tiny rss 中的内容推送到 kindle 上实现 kindle 的 rss 阅读。

kindle 上的阅读体验

不过在最新的 ttrss 上,我发现它已经没法实现分类阅读了,估计是 api 有所改动,毕竟写了也有好几个月了,懒得调整了……

先放上脚本链接,包含 recipe 文件和推送脚本,后者需要 mailgun 账户。

如果你用的是 Linux VPS,那么只要按照calibre 官网上所述的安装方法安装好 calibre,最后将 recipe 文件和 push.sh 放到 VPS 上,修改一些变量就能用了。

如果你用的是 Windows (自己的电脑或者 VPS 都好),那打开 calibre,点新闻抓取,高级,自己添加一个 recipe,将我的 recipe 文件粘贴进去,最后设置登录用户名为: username;http://<ttrss-url>;test,密码为 ttrss 的密码,然后设置自动抓取推送即可。

最后说一句,对此脚本不负任何责任,这玩意需要自己慢慢折腾,我之前没写折腾笔记所以现在懒得写 step-by-step 了……

Firefox 35 下可用的 pentadactyl

pentadactyl 是一个以类 vim 方式操作 Firefox 的插件。

由于某些原因,pentadactyl 并未停止开发,但火狐附加组件页面和官方每日构建页面都停止了更新,导致火狐新版无法支持 。

于是我自己构建了一个版本,是文章发布时的最新源码构建的。放在了百度网盘,需要的人自取。

构建其实也很简单,以 CentOS 为例,假设你安装了 epel ,然后:

yum install mercurial zip make # 安装hg,zip,gmake等依赖
hg clone http://dactyl.googlecode.com/hg/ dactyl # 将 dactyl 的源码克隆到本地
cd dactyl/
make -C pentadactyl xpi # 制作 pentadactyl 的 xpi 文件

然后你会在 downloads 文件夹下发现构建好的 xpi 文件。直接用火狐安装即可。

更新:Firefox 35 可用的版本已经传到了百度网盘

gulp.js – stream 驱动的自动构建工具

最近心情不太好,开始有点自暴自弃。所幸能够写点代码分分心……

开始接触一些前端的项目,就尝试着用一些看起来很 cool 的技术/工具。初步选定的工具包括 jade 、 stylus 和 coffee 。

可是做预编译实在是一个很麻烦的事情,直到我遇见了 gulp.js

gulp.js 是一个简洁明快的自动构建工具,官方文档也异常简洁清晰。主打“stream”式构建,配置文件写起来也是不太复杂。这里针对自己用到的一些插件做简单的介绍。

gulp-concat 是一个将多个文件合并到一起的插件。

gulp-clean 用来清理目标目录中的文件。

gulp-stylusgulp-coffeegulp-jade用来预编译我的代码。

想要达到的效果是:

  1. 将一些静态文件复制到发布目录;
  2. 将框架的 css 与自己的 stylus 编译成的 css 合并;
  3. 将框架的 js 与自己的 coffee 合并;
  4. 将 jade 编译为 html 文件。

目录结构如下:

public/ 存放发布文件
src/ 存放源文件

实现思路:

清理发布目录

var clean = require('gulp-clean');
gulp.task('clean', function () {
    return gulp.src('public').pipe(clean());
});

几乎是最简单的任务。将发布目录整个的删掉。

gulp.src用于读取源文件,这里读取的是public目录;然后将其 pipe 到 gulp-clean 插件,将其清理掉。

处理静态文件

gulp.task('static', function () {
    gulp.src('src/img/**')
        .pipe(gulp.dest('public/img/'));
    gulp.src('src/fonts/**')
        .pipe(gulp.dest('public/fonts/'));
});

和上面的范例类似,只不过用的是gulp.dest,用于将 pipe 过来的文件发布到 public 目录。

注意这里的路径是 src/img/** ,表示对 img 目录下的文件进行递归处理。

构建 jade

var jade = require('gulp-jade');
gulp.task('html', function () {
    return gulp.src(['src/jade/**/*.jade', '!src/jade/partial/**'])
        .pipe(jade())
        .pipe(gulp.dest('public/'));
});

这里只是换用了gulp-jade插件而已。

需要注意的是,这次的路径传入进来的是个数组;数组会如同你想象的那样,将数组中的元素挨个匹配;!开头的表示去除src/jade/partial目录下的所有 *.jade 文件;**/*.jade则表示该目录下递归中所有的 jade 文件。

这里将 gulp 链 return 回去,是为了在处理依赖的时候,能够正确确定函数处理进度,以保证运行顺序。

合并 js 和 css

var concat = require('gulp-concat');
//合并 css
gulp.task('css', function () {
    return gulp.src('src/css/*.css')
        .pipe(concat('0.css'))
        .pipe(gulp.dest('.tmp/css/'));
});
//处理 js
gulp.task('js', function () {
    //加载jquery、modernizr、foundation、vue
    return gulp.src([
        'src/js/vendor/jquery.js',
        'src/js/vendor/modernizr.js',
        'src/js/foundation.min.js',
        'src/js/vendor/vue.min.js'
    ])
        .pipe(concat('0.js'))
        .pipe(gulp.dest('.tmp/js/'));
});

这里用到的是gulp-concat插件。它能把多个文件合并成为同一个。

这里将输出送到了 .tmp 目录下,是为了后续能够处理它。

编译 stylus 和 coffee

var stylus = require('gulp-stylus');
var coffee = require('gulp-coffee');
//stylus 编译
gulp.task('stylus', function () {
    return gulp.src('src/styl/**/*.styl')
        .pipe(stylus())
        .pipe(concat('1.css'))
        .pipe(gulp.dest('.tmp/css/'));
})
//处理 coffee
gulp.task('coffee', function () {
    return gulp.src('src/coffee/**/*.coffee')
        .pipe(coffee({
            bare: true
        }).on('error', gutil.log))
        .pipe(concat('1.js'))
        .pipe(gulp.dest('.tmp/js'));
});

这里依然将输出送到了 .tmp 下。接下来要将 .tmp 下的文件合并为真正能够使用的 css 和 js 文件。

合并临时 css 与 js 文件

gulp.task('concat-css', ['css', 'stylus'], function () {
    return gulp.src('.tmp/css/*')
        .pipe(concat('common.css'))
        .pipe(gulp.dest('public/css'));
});
gulp.task('concat-js', ['js', 'coffee'], function () {
    return gulp.src('.tmp/js/*')
        .pipe(concat('common.js'))
        .pipe(gulp.dest('public/js'));
});

这里用到的是 deps 也就是“依赖”语法。task 的第二个参数是一个数组。在执行这个任务时,会自动执行数组中的任务;并且,当且仅当数组中所有任务执行完毕后,才会执行后面的 function 中的任务。

这里的应用就是,在先合并好了框架的 css 和自己写的 stylus 编译完成之后,再将临时文件中的两组文件合并起来。

清理临时文件

gulp.task('concat-and-clean', ['concat-css', 'concat-js'], function () {
    return gulp.src('.tmp').pipe(clean());
});

这里则是用到了刚刚提到的 gulp=clean 插件和 deps 语法。

默认动作

gulp.task('default', ['concat-and-clean', 'html', 'static']);

在命令行下,执行 gulp 时,则会自动执行 default 任务。这里定义的 default 任务没有事实上的动作;它只是同时执行上面所述的几个任务,然后自己退出。

监视改动

gulp.task('watch', ['default'], function () {
    //js
    gulp.watch('src/coffee/**', ['concat-js']);
    //css
    gulp.watch('src/styl/**', ['concat-css']);
    //html
    gulp.watch('src/jade/**', ['html']);
    //静态
    gulp.watch('src/img/**', ['static']);
})

gulp.watch 能够监视指定文件的改动,并启动任务;也就是说,当src/coffee/中的文件改动时,gulp 会自动执行 concat-js 任务。

然后我们只需要在命令行中输入 gulp watch ,gulp 将会自动跑一轮 default 任务,然后监视我们的源文件;当发现文件变动时,将自动执行编译。

至此,我的 gulpfile.js 就编写完毕了。Enjoy it!

Goodbye , LastPass . Hello , KeePass !

一直以来我都高度依赖 LastPass ,由于自己的分级密码策略,我实在是记不住哪些网站用了哪些密码。好在有了 LastPass ,让我的生命中少了一大堆烦恼。

随着审美观的提高,我不断发现 LastPass 的致命软肋。如,密码数据库保存在服务器上;又如,连接经常不够稳定;再如,保存密码流程真真是二逼兮兮的。直到我发现了 KeePass ,这一切都不再烦恼。

KeePass 是一个优秀的开源密码管理方案。由于其并不把数据存放在服务器上,因此一切关于网站会不会一直存活下去的担心皆可避免;另外由于其开源的特性,让你的选择不只有一种——光是 iOS 客户端就有长长的一串。

这里我选用的是官方的 KeePass 2.25 。在 KeePass 里很容易把 LastPass 的数据导入进来,只需点击文件->导入->LastPass CSV,即可导入 LastPass 导出的 csv 文件了。

KeePass丰富的导入功能

在这张图里也可以看到,KeePass 能够导入各种各样的格式。

导入之后,就可以开始使用 KeePass 了。这里顺便介绍一些实用的插件。

首先是配合 FireFox 使用的 KeeFox 。在 Mozilla 扩展中心下载 KeeFox 之后,关闭 KeePass ,根据提示选择安装路径,即可安装 KeePass 插件。这时启动 KeePass ,右键点击你存放密码的目录,选择 Set as KeeFox start group ,就算配置完成了。之后直接在 Firefox 中就能享受到 KeePass 的贴心了。

然后是 KeeOtp 。这款插件支持将 Google 二次验证导入 KeePass 中,这样就不需要去找手机了,同时手机丢失了也不怕, KeePass 里还有备份。插件的用法很简单,右键点击条目选择 Timed One Time Password ,复制粘贴网页中的密钥,就能成功设置了。

另外给出几个小提示。

其一是自动登录 KeePass 的方法。 KeePass 确实够好用,可是问题是每次都输入长长的密码实在是很不环保啊!KeePass 提供了-pw:123456这样的命令行参数,但是把密码写到命令行里恐怕和没有密码没区别。解决的方法,是使用内置的{PASSWORD_ENC}功能和-pw-enc命令行。根据官方说明,{PASSWORD_ENC}是一种只限当前用户使用的加密功能,也只有 KeePass 能够解密,所以可以安心使用。

具体的方法是,创建一个条目,用户名随意,密码写成你的 KeePass 的密码,在编辑->自动输入中选择“替代默认规则”并写入规则:{PASSWORD_ENC}确定保存。然后在 KeePass 目录下新建一个文件,叫 start.bat ,用记事本打开,输入:start KeePass.exe "(KeePass数据库目录)" -pw-enc:。此时将光标放到最后,切换到 KeePass 里,右键刚刚的条目,选择“自动输入”。然后……你就可以看到你的记事本里的字符在疯狂的跳动,大概十多秒的样子输入了一大堆 Base64 编码的玩意。现在,可以保存关闭了,下次双击 start.bat 就可以自动登录了。至于安全性嘛……总之不能和便利性同在。

KeePass密码加密

其二是自动保存的触发器。点击“工具->触发器”,左下角的“工具”中粘贴下面的脚本即可:

<?xml version="1.0" encoding="utf-8"?>
<TriggerCollection xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Triggers>
        <Trigger>
            <Guid>EXkzOtjQEEqLvtvmzbDD+Q==</Guid>
            <Name>自动存盘</Name>
            <Comments>via http://best33.com</Comments>
            <Events>
                <Event>
                    <TypeGuid>jRLUmvLLT/eo78/arGJomQ==</TypeGuid>
                    <Parameters />
                </Event>
            </Events>
            <Conditions>
                <Condition>
                    <TypeGuid>08r67ygqRkqZkNhl/OAW7Q==</TypeGuid>
                    <Parameters />
                    <Negate>false</Negate>
                </Condition>
            </Conditions>
            <Actions>
                <Action>
                    <TypeGuid>9VdhS/hMQV2pE3o5zRDwvQ==</TypeGuid>
                    <Parameters />
                </Action>
            </Actions>
        </Trigger>
    </Triggers>
</TriggerCollection>

其三是自动同步。这个嘛比较简单,数据文件放到 OneDrive/DropBox/Google Drive 里就好了。为什么是这三个网盘呢?因为 KeePass2Android 只支持这三个网盘……

当然了,你有自己的 FTP/WebDav 服务器啥的也是可以直接用 KeePass 打开的,只不过存盘太慢了……所以还是用同步盘吧XD。

QQ邮箱什么的

一直以来都喜欢腾讯家的邮箱,稳定,低调,不浮夸,算是腾讯产品线中不可多得的良心产品。在国内访问的速度比起Gmail来那叫一个快……大概是因为没有其它可以做对比的对象吧,感觉QQ邮箱确实还是做得挺好的。对于我这种不能免俗的在桌面上使用Windows+QQ的忠实用户,不用再开一个客户端来进行邮件提醒真是有够给力的。

QQ邮箱团队给我的感觉是一个很具有活力的团队,经常对邮箱进行一些细致的思考和修改,每次看更新日记都有一种“咦,和我想得一样”的感觉,大概是我和邮箱团队的缘分吧~笑。(顺便说,Gmail每次更新都有一种“咦,这个太棒了,怎么会这样?”的感觉……)

今天爬上邮箱,随手点了一下容量数字,发现又可以升级了。原本是有1048576G(好像是1024TB吧?相当于1PB来着。),点了一下升级,按QQ邮箱的翻倍策略我以为我的邮箱要到2个PB的容量了,没想到我看到了这样一个界面:

咦,当时就震惊了,居然是无限容量~
嘛,虽然说对“无限”这种概念全是不是很有感觉,但是怎么说呢,看到还是忍不住要截图炫耀一下=-=事实上,我的其它的邮箱基本都是通过QQ邮箱管理的,所以日常使用还是比较多的。刚刚看了一下,使用概况大概是这个样子:

用掉了4个G,也算是重度的QQ邮箱用户了。之前也说了QQ邮箱的好处,就是在于免客户端、速度快、访问稳定,UI基本上也中规中矩,不浮夸,看起来很舒服。有邮箱独立密码在,在QQ号被钓鱼的时候也能减小风险,整体来说是一个不错的邮箱选择,在国内大概找不出第二家这样好的邮箱服务吧。什么?你说网易?我就不想吐槽163.com/126.com的广告小尾巴了,这都什么年代了,还不取消么?

对于逼格更高的Gmail、Outlook.com之流,对于半个小时检查一次邮件、又无比抵抗邮件客户端的我,只能说,我确实还没有那么高的逼格能够hold住那种销魂的访问速度……

唔,好吧,我感觉这篇文章会引来好多吐槽啊……

Win8下的鼠标滚轮穿透软件 AlwaysMouseWheel

新装了Windows8.1,虽然是没有激活但也是能够正常使用的。还好主要生产力工具FireFox和Sublime Text 2都是绿色版,没有多少折腾就进入了正常的状态。

嗯,但是换了系统总是会有些纠结的,比如我就发现我一直使用的MouseInc的鼠标滚轮穿透功能失效了。嗯……也许不是一个普遍现象,因为没有Google到相关的feedback。

于是想着再找另外一个轮子,反正这样的轮子已经造过很多了。找到了一款叫AlwaysMouseWheel的软件。嗯,只有这么一个功能,实测好用。

对了,你可以选择官方下载,或者微云下载