@差生文具多
@差生文具多
关注的小组(6)
动态 帖子 19 评论 111 短评 5 收到的赞 228 送出的赞 155
  1. 差生文具多   在小组 2047 回答问题

    为什么有人意淫新疆能独立?

    楼主省省吧。

    1. 新疆非常不安全、不稳定。不要拿政府拍的宣传片来哄鬼,有本事就放开媒体自由进出采访。他们敢吗?我看他们不敢。
    2. 新疆的政治氛围异常肃杀,街头搜身随处可见,连上网都有墙中墙。全自治区断网一年的事情还历历在目,偌大一个自治区连百度网盘都用不了,只能上天山网。
    3. 不要逢人就复读新疆房价低,东北三省、西南边境、还有全国各个十八线冷门小城市房价低的多了去了,楼主有机会去全国各地走走。哦,原来新疆户口旅行受限,走不了。
    4. 众所周知,新疆户口出了名的难迁出,定居新疆基本是个有去无回的大坑。人往高处走,谁会牺牲自己和后代发展的机会搬进一个大监狱?楼主认同汉族民族主义,不要绑架其他人。
    5. 我不在乎新疆将来要不要独立,不过可以说,新疆现在的民族比例是靠内地补贴和人为设置迁出障碍才勉强维持的,一旦放开,很多有条件的人巴不得离开。

    你要宣传请去局域网里宣传,那里的粉红爱听你说话,他们说不定还会信。你跑到外面费这个力干嘛,莫不是真的有任务?

  2. 差生文具多   在小组 2047 回答问题

    品葱这么专制怎么会混进非常多的粉红?

    从来不看品葱,能不能搬运几条过来鉴定一下?

  3. 差生文具多   在小组 江湖 回复文章

    rebecca我想问你,你男友之前受不了和你分手,你都是这样事后骚扰人家1,2年下来的?这就是你40岁都嫁不出去的原因吧?

    2047被蔡伟亲自认证过,有段时间端点星github上的连接指向2047。

    真是皇帝不急太监急,当事人本人都认可了,楼主还在这里嘶吼“2047骗取2049遗产”,哈哈。

  4. 差生文具多   在小组 2047 回复文章

    六块腹肌和六间房子

    足够瘦就显腹肌了。

  5. 差生文具多   在小组 2047 回复文章

    六块腹肌和六间房子

    六套房子妥妥的有闲阶级了。不过我也来爆论两句:除去不缺时间的学生党,健身确实是反映生活品质的指标。

    当然,健身是指讲究一定围度和体型的健身。很多体脂低的人都有明显的腹肌,如果单纯想要八块腹肌,节食一个月或者做抽脂手术去掉腹部脂肪就行了。但是这样的“八块腹肌”不健康,不在讨论范围之内。

    健身讲究三要素:锻炼、营养、休息,三者缺一不可。锻炼的作用不必说,只吃只睡不锻炼会变肥宅。不过反过来说,中国满大街都是不缺锻炼机会的体力劳动者,没见过哪个练出腰窝倒三角,这就说明营养和休息和锻炼同等重要。

    就拿营养来说,健身推荐的蛋白质摄入量是每日每公斤体重2克。假如一个人体重70kg,那么他每天需要摄入140克蛋白质。动物肉含有20%蛋白质,140g蛋白质等价于吃700g肉,而这些肉食超过95%中国人的合理负担能力。换句话说,至少得牛肉自由吧。

    所以一个人身材好,有一定概率表明这个人:1)坚持锻炼——说明生活自律;2)营养好——负担的起高蛋白饮食,经济能力不差;3)休息充足——有轻松稳定的工作,有足够闲暇休息、健身。这三点足以超过大多数人。

  6. 差生文具多   在小组 江湖 回复文章

    你为什么不应轻信小二的人设和安全建议

    自行搜索端点星案。小二是一个现实世界存在的人,他被共产党逮捕、关押、起诉,这些事情网上可以搜到,不知你从何得出小二是匪谍的结论。

    这篇文章是BE4写的,其中有些说法并不真实。站里也有小二对这篇文章的回应,

    https://2047.one/t/4064

  7. 差生文具多   在小组 2047 回复文章

    终于找到家了,心旷神怡的感觉!顺便问下TOR的问题

    您的解释是错误的。tor有三层TLS,TLS流量完全加密,且可抵御中间人攻击。

    “运营商和GFW可能也开了Tor浏览器……用他们的Tor来访问并转发给你”,根本做不到而且没有必要。

  8. 差生文具多   在小组 2047 回答问题

    请问有什么人知道这个电纸书“网站”的来源或是一些背景之类的吗

    ip:"157.7.135.42",
    hostname:"v157-7-135-42.myvps.jp",
    city:"Tokyo",
    region:"Tokyo",
    country:"JP",
    loc:"35.6895,139.6917",
    org:"AS7506 GMO Internet,Inc",
    postal:"101-8656",
    

    看上去就是一个文件分享站,并不需要什么背景,一个月花十几块租台VPS就可以做。

    这个站没有绑定域名,裸IP看上去比较奇怪而已。

  9. 差生文具多   在小组 江湖 回复文章

    品葱一头鹿儿的真实身份

    我从体制内的朋友那里了解到,墙外有大量中宣部的水军,这些水军有意识的离间分化墙外“反贼”站。这篇《鹿儿的真实身份》就是三局某实习生的作品。

    宣传部门同时还和网警合作,在各个网站注册大量一次性小号,扮成疯子来刺激用户实时发言,以通过流量分析定位用户。

    具体证据我就不贴了,以免中共社工我。

  10. 差生文具多   在小组 2047 回复文章

    净网志愿者协会:爆破2047

    不可能。

    如果有使用云上IT服务的经验就知道,没有服务商会因为占用太多空间就随机清除内容。购买云服务的时候,硬盘分配多少都是写好的,如果超出了这个数,结果就和写满本地电脑一样——操作系统提示硬盘满,然后该怎样就怎样,对linux服务器而言这不会有任何影响。

    事实上云服务里硬盘空间真的很廉价,值钱的是CPU时间和流量。但是哪怕CPU时间和流量用完了,服务商至多会隔离你的实例,不让外网访问,不可能也没必要去清硬盘的。

  11. 差生文具多   在小组 2047 回复文章

    净网志愿者协会:爆破2047

    这个说法是前站长为了diss品葱的技术水平,借坡下驴放出来的谣言。深究起来漏洞百出。

    我对这个说法的技术分析见这里: https://2047.one/t/19995

  12. 差生文具多   在小组 2047 回复文章

    净网志愿者协会:爆破2047

    看上去像是小说。

    好奇为什么反派叫2047,而不叫2046或者2048

  13. 差生文具多   在小组 2047 发表文章

    净网志愿者协会:爆破2047

    11月14号,上午8点整。

    阿源从厨房端出又一碗热气腾腾的鸡蛋挂面,坐在沙发上,开始吃起了早餐。

    依旧是新闻台,不过今天的早间新闻并没有出现能让阿源觉得有价值的营养内容。多半是一些娱乐、体育方面的小事儿。

    昨晚0:00分,阿源准时入睡,为了今天下午的校园“首届攻防大赛”…哦不,是校园社团文艺汇演,做好精神上的准备。他可不想带着个熊猫眼在直播中露脸。

    吃完面条后,他便钻研起好基友叶聪准备好的PPT内容了。研究好此次攻防设置后,他便打开了净协靶场,练练手。

    这里科普一下“网络攻防”和“靶场”的概念:网络攻防,亦称“网络对抗”。网络攻击与网络防护的合称。网络攻击指综合利用目标网络存在的漏洞和安全缺陷对该网络系统的硬件、软件及其系统中的数据进行攻击,主要包括踩点、扫描、获取访问权限、权限提升、控制信息、掩盖痕迹、创建后门等步骤;网络防护指综合利用己方网络系统功能和技术手段保护己方网络和设备,使信息数据在存储和传输过程中不被截获、仿冒、窃取、篡改或消除,包括加密技术、访问控制、检测技术、监控技术、审计技术等。网络攻击和网络防护是一对“矛”和“盾”的关系,网络攻击一般超前于网络防护。

    靶场,即网络靶场(Cyber Range)是一种基于虚拟化技术,对真实网络空间中的网络架构、系统设备、业务流程的运行状态及运行环境进行模拟和复现的技术或产品,以更有效地实现与网络安全相关的学习、研究、检验、竞赛、演习等行为,从而提高人员及机构的网络安全对抗水平。网络靶场作为支撑网络空间安全技术验证、网络武器装备试验、攻防对抗演练和网络风险评估的重要基础设施,成为新兴网络安全战略、专业人才队伍建设的重要支撑手段。

    耗时40分钟后,阿源便顺利搞定了中等级别的14个攻防演练关卡,他赏了自己大腿一巴掌(因为莫名的精神兴奋),接着又开始挑战起了高手级别的演练关卡。

    过了一会儿,来了一通电话。阿源应声接起,对面传来的是三哥的声音:“顾源啊,这里有你需要的‘1602136’专案被捕人员名单和茂南区公安局、看守所全体职员名单,你三哥我随时等你来拿啊。”

    “好嘞,下午我回学校顺路再捎上。谢谢三哥了啊。”阿源回复道,心中只是念道“Cowboy他们效率挺快啊……”

    转眼已是早10点,搞定完攻防练习后,阿源便像往常一样,躺在沙发上,浏览了一下音系的消息并冒了几个泡,开始忙活了。

    昨晚从Alex那儿获取了“天权”的账号后,他就人肉出了两个账号所绑定的手机号码:18769909471,归属地是山东青岛。他接着昨晚的调查思路,从机主信息、账号实名信息两个切入口查起。

    18769909471,机主姓名:王子栋。注册时间:2019年4月10日。身份证号:370211199702053112。

    匹配了账号实名信息后,顾源便排除了挡刀的80%可能性。接着,他就跑到音系里,去打听打听这个“天权”的事迹了。

    据阿源又一个钟头下来的溯源分析,得出了以下报告:

    王子栋(1997.2.5 - ),山东青岛人,毕业于临沂大学计算机网络专业2015级专科。 详细住址:临沂兰山区工业大道1号。 其父王强,住址为山东青岛市黄岛区双珠路357号。 圈名天权,著名精日分子及恶俗领袖。

    诈骗犯王子栋是一个从事多年诈骗,拥有丰富诈骗经验的淘宝差评师,职业网黑,拥有一个小规模诈骗团队。 王子栋还有一项惊人的违法技能,就是出别人的真实姓名,上网IP甚至户籍资料。 王子栋在2014年接触了日系这个团体,后来开始组建自己的势力,当上了精神日本人和反社会分子,创立真支黑群以钓鱼取乐,经过三年多的发展,在手下培养了一大批渔夫,吸纳了卫校网黑杨子印,谷鑫,丁海峰等人,还巴结拉拢了不少恶俗人。 2016年10月,王子栋利用杨永信电死人的事件进行炒作,创立了杨永信吧钓鱼群,利用杨永信正面言论钓鱼,甚至伪装成日本人。之后,王子栋收买了几个精日管理员,使得钓鱼群最终突破千人。

    其曾因涉嫌人肉网络小说粉丝致使后者不堪忍受而自杀,于2018年入狱服刑了一年。

    搞清楚“天权”的身份信息后,他就开始实施早已铺设好的“计划”中的下一步了……

    顾源联系上了林庆、叶聪、钟洋三个好基友,又联系了社团里在渗透测试(证明网络防御按照预期计划正常运行而提供的一种机制)方面技术高超的朋友,又拉上了几个协会猿明园(董事会直接建立的面向网络安全、信息技术的专项团队,净协核心技术团队,第二阶级)的会友,组成了一个临时“攻击指挥部”群组。而他们的目标,正是2047论坛。

    顾源的计划很简单,从一开始在调查2047论坛背后的运维人员时,他就已经谋划出了这个可谓“一石多鸟”的方案。

    第一步,把2047给打了,宣布对纳系的攻击,然后此时“Dawn”再跳出来,指出运维弱点,拉拢自己与纳系的距离。第二步,窃取2047的所有用户数据,交给协会处置。第三步,摸清攻击思路后,再试图在未来对恶俗维基开展攻击,然后顺势而上,拿到更多好处。

    而且,一旦2047这一“历史悠久”的键政老巢被端,将会让不计其数的小鬼涌入其它的纳系据点,鉴于纳系各分流中互相的敌视,恐怕得引发一次纳系内部的大型内乱,而这2047正是导火索。

    渗透攻击开始20分钟后,一些正在2047上活跃的小鬼们便发现站点无法响应他们的操作了。又过了一会儿,有大批用户反映自己的账号数据被删除了。李谪刚睡醒,就受到了连绵不断的“提示音”攻击,他骂街着把手机调到了静音,然后打开浏览器,准备前往2047看看究竟是发生了啥情况。

    结果,他发现2047进不去了。

    “他妈的,什么情况?”李谪骂道,又跑去联系梁智星和王子栋,前者根本没把2047当回事,不清楚2047发生了啥,反而怒骂李谪“没事找事”。

    而后者王子栋,则在质问下讪讪地告诉李谪:“你傻啊,论坛被人给打了!数据库还被人删了!”

    李谪心头一颤,自己好不容易从黎签那里拿到的站长权限,和2047的一站之长名誉,顷刻间消失了。

    只见李谪气急败坏地瞎骂了几句王子栋,又绞尽脑汁地试图通过发表一篇“站点维护声明”换回脸面。不一会儿,李谪在其它纳系据点和自己的推特空间都发了一篇“关于2047论坛进行长期维护的通知”,内容对维护的原因含糊其辞,甚至表示了将会在维护后给各位带来全新的体验。

    然而,真正对2047有技术维护能力的人,“天权”王子栋,对此嗤之以鼻。他警告李谪,数据的丢失是不可逆的,你可以买新域名新服务器重建论坛,但用户数据、所有的帖子等全都回不来了。

    李谪并不明白王子栋的意思,他只是发了一条语音:“CNMD王子栋!你赶紧想办法把我的论坛搞回来!!!”

    王子栋对此选择了无视,接着补充他的警告:攻击论坛的人尚且不明,而且对方的实力强硬,目前他还看不出对方是用什么手段让论坛猝死的。数据的备份他也没有,可能前站长黎签那边还有,只是黎签现已被捕,恐怕2047是不能复活的了。

    就在2047那边乱成一锅粥的时候,这边的顾源可是开心得不得了。他与攻击团队互相庆祝了一番后,便开展了他计划的下一步:借机拉拢纳系小鬼。

    然而,2047事件的关注者,可不是只有小鬼们而已……

  14. 差生文具多   在小组 2047 回复文章

    我们应正视反贼圈整体素质低下,短期内无可能推动政治变革的事实

    我是个现实主义者,对几个小小的网站就能推动什么政治变革不做期待。在我看来,“反贼”社区最重要的是生存能力,只有保证社区活下去,才能期望更宏大的愿景。

    我把社区的生存能力归纳为两点:技术上的生存能力,和文化上的生存能力。

    技术上的生存能力体现在网络安全上。众所周知墙外社区是中共的眼中钉肉中刺,中共必然会投入大量人力物力,打掉墙外有组织的声音。因此社区的运营者和参与者学习安全技术,提高自己的网络安全意识就非常重要。不管有多么高明的政治理念,第一位永远是保证自己的安全。

    我把文化上的生存能力定义为社区的自持力。如果一个社区管理不当,总是流失用户,那么再强的安全能力都没有意义。“反贼”社区要长期存在,首先要保证的是自我持续,合理管控内部冲突,不至于因为人气流失而倒闭。

    政治上的变革更多要看人心大势,“反贼”社区要做的就是保证自己的生存,在合适的时机出现时推动一把。一味的急于求成,甚至搞到投毒放火决水,就变成恐怖组织了。

  15. 差生文具多   在小组 江湖 回复文章

    品葱一头鹿儿的真实身份

    这文章明显是鹿儿的仇人编造的,从头到尾都是臆测。

    一只鹿儿是中国北方某地的人。她在大学期间出国留学,申请工作的时候被一个中资公司录用。这个中资公司有中国军方的背景。她的上司欣赏她的一些特长,于是推荐她接受一个培训,然后为中国国家安全部港澳台局工作。

    要指控某人是匪谍,就拿出证据,比如对方收受中共资助的汇款单,或者对方联络中共的通信记录。搁这儿编了一大串故事,什么鹿儿是北方人,被中资公司录用,请问原作者能拿出一分证据支持这个说法吗?

    你可以不喜欢品葱的政治立场,或者看不惯一只鹿儿的管理操作。但是这种编故事害人,纯纯的小人做派。

  16. 差生文具多   在小组 2047 回答问题

    如何评价我李家隆给刘仲敬戴绿帽一事?

    现任妻子婚前谈过男友不能叫绿吧。

  17. 差生文具多   在小组 2047 回复文章

    中国每10万人仅有3.6张病床

    对比一下这则新闻:山东拟投资超230亿人民币建方舱医院 - 联合早报

    共产党的无耻文人吹嘘时,动辄发达国家粉碎机、集中力量办大事,谈到民生的时候又换了张嘴脸,开始讲人均资源不足,哭穷卖惨。然而这一年半以来,直接花在清零上面的钱估计至少有五千亿,造成的间接损失至少几万亿,足够把全国的医保基金翻一倍还多。

  18. 差生文具多   在小组 国家局域网研究所 回复文章

    一种可能可行的墙内直连从官方渠道下载Tor的方法(利用GetTor)

    网警看不到你用tor,网警不关心也没有必要关心你是不是在用tor……

    很多翻墙用户高估了自己对网警的价值,这些翻墙用户没有也不打算也不可能发表任何有价值、有争议的政治言论,不存在独立的opinion。类似于看完电视新闻之后跑到你面前,跟你复述主持人用到的新词。他们对“网警”的价值几乎为零。

    但是这部分用户却因为恐惧中共,在加固网络安全上投入了不成比例的精力,这种做法不仅是自己吓唬自己,也吓唬其他人。宣传中共的技侦手段多么强大、多么高明,客观上起到了帮助中共维稳的作用。

    我的建议是,翻墙软件足够掩盖tor流量,如果不放心,里面设置obfs4网桥一样可以起到混淆的作用。有兴趣的还可以试试i2p。

    Tor团队的开发人手有限,TBB换装Arti还要几年。不过Arti已经发布了1.x版(production ready),Arti的代码库里有官方的Arti+TBB教程: https://crates.io/crates/arti

  19. 差生文具多   在小组 国家局域网研究所 回复文章

    一种可能可行的墙内直连从官方渠道下载Tor的方法(利用GetTor)

    先用迷雾通翻墙,再用tor浏览发帖就足够了,tor自带的可插拔传输未必比迷雾通安全性更高。

    普通人上网,应该多关注社会工程方面的安全,关注网络安全是好事,但也不必对一些安全特性太较真。

    真要较真的话,Tor的代码经过十多年的开发已经很难维护了,事实上很多人追求的“安全上网”的根基就建立在屎山上。如果可能的话,可以用Arti(tor团队开发的rust版本)作为tor的替代品。

  20. 差生文具多   在小组 2047 回复文章

    江泽民死了

    我以为,江人品怎么样不重要,关键是又有了个合法上街的理由。死亡之后可以做一点贡献

  21. 差生文具多   在小组 2047 回复文章

    江泽民死了

    “1989年4月15日,前任中共中央总书记胡耀邦在北京病逝,享寿74岁,他的死是六四天安门事件的导火线”

  22. 差生文具多   在小组 2047 发表文章

    江泽民死了

    据新华社电

    中国共产党中央委员会、中华人民共和国全国人民代表大会常务委员会、中华人民共和国国务院、中国人民政治协商会议全国委员会、中国共产党和中华人民共和国中央军事委员会,极其悲痛地向全党全军全国各族人民通告:我们敬爱的江泽民同志患白血病合并多脏器功能衰竭,抢救无效,于2022年11月30日12时13分在上海逝世,享年96岁。

  23. 差生文具多   在小组 国家局域网研究所 回复文章

    《连线》杂志报道rust:接管技术的安全编程语言

    我认为原因是C/C++存量代码大,毕竟有过去30多年的积累,rust要短时间“替代C”几乎不可能,很多老项目还会招C++程序员来做。

    还有一个原因是人才问题,一代的CTO都是学C++过来的(例如编程随想),他们做技术选型的时候当然愿意选技术更成熟、自己更熟悉的C系语言来做。

    从招聘需求也能看出来,传统技术,老项目用C系的多,新技术、新项目用rust的多,例如加密货币、分布式数据库。

    我个人认为学C++和学rust完全不矛盾,用过C++以后,用rust的感觉是:真香。而且学rust也可以反过来加深对C++的理解。

  24. 差生文具多   在小组 国家局域网研究所 回复文章

    有什么客户端的JS白名单工具可以根据JS的实际内容决定是否加载?

    不行,Tor浏览器的限制程度有限。如果只追求安全,那么Tor浏览器确实够用了,但有些用户希望在限制危险JS API的基础上,自己做更多定制。

    举个例子,Vibration API允许JS代码震动设备,仅从安全角度讲这个API是无害的,但少数网站(特别是弹窗)利用这个功能骚扰用户。再比如Page Visibility API在Tor浏览器上是可用的,这API可以允许JS了解当前网页是否对用户可见,网课前端检测用户状态就是这个原理。

    我认为这些恼人的问题不是JS的缘故,而要归结于网页设计者不尊重用户。如果可能,浏览器应该提供禁用这些API的选项,或者更进一步提供虚假值,给用户提供更多的选项

  25. 差生文具多   在小组 国家局域网研究所 发表文章

    Arti: 一个用内存安全语言Rust实现的Tor节点程序

    大多数情况下提到Tor,指的是用C语言实现的Tor。说起Tor大家会想到安全、隐私,然而事实上,C语言实现的Tor经过十多年的开发迭代,代码已经变成了屎山。

    你没看错,用Tor团队的说法,目前C语言实现的Tor的情况是

    What's more, our existing C implementation has grown over the years to have a not-so-modular design: nearly everything is connected to everything else, which makes it even more difficult to analyze the code and make safe improvements. One thing that we found, however, was that our existing C code was not modular enough to be easily rewritten. (Rust's security guarantees depend on Rust code interacting with other Rust code, so to get any benefit, you need to rewrite a module at a time rather than just one function at a time.) The parts of the code that were isolated enough to replace were mostly trivial, and seemed not worth the effort—whereas the parts that most needed replacement were to intertwined with each other to practically disentangle. We tried to disentangle our modules, but it proved impractical to do so without destabilizing the codebase.

    简单来说,Tor开发团队试着用Rust语言向Tor代码中添加一些新功能,结果发现旧代码耦合在一起,修改一处,其它地方就要出乱子,不得已只好彻底推翻重写。

    从前年(2020)开始,Tor开发团队就开始着手用内存安全语言Rust重写Tor,重写后的Tor叫做Arti,架构设计更合理,开发语言Rust当然也更安全。目前Arti已经推出了1.0,可以用于生产环境。

    有人会问,Go或Java不也是内存安全语言吗?这个Arti不能用Go或者Java重写吗?

    先不谈性能问题,只就语言设计来说,Rust语言的不止有内存安全的特点,它还有很多非常严谨的代码防呆设计来阻止你写错代码,除非你编程思路有问题,或者故意写错代码,否则很难出错。Tor开发团队也有相同的感慨:

    At every stage, we've encountered way fewer bugs than during comparable C development. The bugs that we have encountered have almost all been semantic/algorithmic mistakes (real programming issues), not mistakes in using the Rust language and its facilities. Rust has a reputation for being a difficult language with a picky compiler - but the pickiness of the compiler has been a great boon. Generally speaking, if our Rust code compiles and passes its tests, it is much likelier to be correct than our C code under the same conditions.

    (在开发过程的每个阶段,我们遇到的错误都比用C语言开发的对应阶段少得多。我们遇到的 bug几乎都是语义/算法错误(即真正的编程问题),而不是使用Rust语言本身和开发设施的错误。Rust以复杂的语言和挑剔的编译器而著称——但是挑剔的编译器是一个很大的优点。一般来说,只要我们的Rust代码编译并通过了测试,那么比起C代码,相同条件下Rust代码就更可能正确。)

    除此之外,Arti还在Tor的基础上,添加了很多新的安全特性,例如对流量分析的抵抗能力。

    目前安装Arti需要电脑上有Rust编译器,如果你已经安装了Rust编译套件(Cargo),可以运行以下指令安装Arti:

    cargo install arti
    

    如果没有安装Rust,可以参考Rust官网的指南安装Rust编译套件

  26. 差生文具多   在小组 2047 回复文章

    品葱已出现并号召对公务员食堂投毒的行动派

    这基层单位领导缺乏常识。《明史》记载:

    晉恭王棡,太祖第三子也。學文於宋濂,學書於杜環,洪武三年封。十一年就籓太原,中道笞膳夫。帝馳諭曰:「吾帥群英平禍亂,不為姑息。獨膳夫徐興祖,事吾二十三年未嘗折辱。怨不在大,小子識之。」

    干什么都别得罪基层服务人员,人家如果存心报复,在饭菜中做点手脚,还不是轻而易举,让人死都不知道怎么死的。

  27. 差生文具多   在小组 国家局域网研究所 回复文章

    VirtualBox+Whonix隔离方案和Whonix设置中文环境

    whonix用来跑暗网服务应该是神器,双重虚拟机+安全强化。可惜在中国不太适用,国内网络上先翻墙再跑服务反而增加了风险。

    whonix有一个不错的用途是跑XMR全节点,因为全节点无法用代理,可以把全节点扔进虚拟机里面运行。

  28. 差生文具多   在小组 国家局域网研究所 回复文章

    迷霧通到底咋了?一分鐘恨不得掉線5次。

    #195476

    这是两码事。

    付费用户花钱买服务,完全有资格对服务不稳定提出意见。你模仿的这个例子的恰当类比场景是:付费用户要求迷雾通添加各种额外功能,这种情形确实不在服务方的义务之内。

    不过说回来,迷雾通每次大规模掉线之后都会补偿用户时长,这也没有什么可以指摘的。

  29. 差生文具多   在小组 2047 回复文章

    聊下自己准备毕业考英语时遇到的问题

    中国的英语应试考主要考阅读,而阅读成绩主要依赖单词量。所以我建议您可以以背单词为主,背熟所有大学四级单词,然后买一两本入门语法树,了解一下语法。等单词背熟之后,可以开始买毕业考试相应难度的阅读试题,每天刷1-2套,就可以通过毕业考试了。

  30. 差生文具多   在小组 国家局域网研究所 回复文章

    有什么客户端的JS白名单工具可以根据JS的实际内容决定是否加载?

    我想到两种办法:

    1. 写一个油猴子脚本,记录下网站JS的md5,如果md5发生改变则不再加载。缺点是很多网站的js都会定期更新,有可能网站更新了,但是你的插件发现md5不匹配把它拦截了。

    2. 可以考虑拦截敏感JS API,我认为这个更可行,但是工程量较大。举例来说,dom操作是非敏感api,其它api都可以考虑拦截,比如臭名昭著的webrtc(可绕过代理获取真实ip),beacon(经常用来跟踪用户),还有各种乱七八糟的ajax请求也可以直接拦了。

    多说一句,我认为js api缺少有效的权限管理,大多数js api是完全无害的,它们只用来改变网页的显示效果。但还有一些js api权限很大,比如很多网课会用js检测用户是否打开了当前tab,这就侵害了用户的自主权。我认为最好可以像安卓那样,由用户选择性的禁用一些api。

  31. 差生文具多   在小组 国家局域网研究所 发表文章

    谈谈thphd的《对养猫君对葱爆的分析的分析》一文的错误之处

    对养猫君对葱爆的分析的分析

    我最近翻站里的旧文章,发现这篇一年以前的文章里充斥着大量的IT常识错误,作者的语气还颇为自信,气势很能唬住一些外行读者。这样一篇充满低级错误的文章以贵站(前)站长的身份发在站里,实属拉低了贵站技术的上限。不知那些专业的IT人士看到这样一篇文章,会对2047的技术水平作何感想?因此,我认为有必要写一篇文章,指出《葱爆的分析的分析》的错误之处。

    thphd在这篇文章中的技术分析有很多错误。我不清楚是他自己一知半解就信口开河,还是自己清楚但故意误导读者。比如,技术分析部分的第二段就是如此:

    MySQL遇到磁盘已满的情况,并不会返回DISK_FULL错误并拒绝服务,而会直接当场卡死,除非非常了解mysql工作原理,否则只能强行重启:https://dev.mysql.com/doc/refman/8.0/en/full-disk.html

    我很疑惑thphd是否真的看过这个链接里的内容,这个链接里讲的是MySQL如何处理磁盘写满的情况。根据MySQL文档的说明,在磁盘写满时,MySQL并不会“卡死”,而只是每隔一分钟检查一下是否有足够的空间写入,如果有空间就写入,没有空间就不写入,就好像什么都没发生一样(it continues as if nothing had happened)。

    就算不去读MySQL的文档,凭常识也可以推断出,MySQL作为一款全世界最流行的数据库系统,背后又有Oracle这样的公司支持,必然会考虑到磁盘写满这样的常见情况。所谓MySQL“卡死”纯属缺乏计算机常识的臆测。

    这篇文章里更有一些极度缺乏常识的观点,例如:

    因为开机过程也是需要写入磁盘的,磁盘空间不足可能导致开机卡死。而云服务器无法开机就连不上,也就无法进行远程操作

    我不知道thphd是否有操作Linux系统的经验。Linux系统非常可靠,这和我们日常使用windows电脑的经验不同,即使硬盘写满,内存占满,CPU使用率100%,也不会影响正常使用,当然也不影响远程连接。事实上在商业环境中,操作系统满负荷重载运行是很正常的事情(包括偶尔写满硬盘),否则公司投资了昂贵的IT基础设施又不能跑满,岂不是严重的浪费。

    下面的分析更是看似有理,实则是满篇的胡说八道:

    所以另一种情况是,品葱站长强行重启了服务器,开启了数据库,数据库尝试从上一次强行重启的地方开始恢复。由于几乎所有数据库都依赖某种b+tree,而b+tree最流行的实现是leveldb(myrocks),leveldb极度依赖底层磁盘的顺序写入特性,如果底层磁盘(这个例子中是虚拟磁盘)不完全是顺序写入的(例如为了性能开启写入缓存),那么强行重启就会导致丢失最近写入的几个ldb文件,而leveldb在这种故障模式下完全无法recover(因为作者假定磁盘是强顺序写入的),使得强行重启有一定几率会导致丢失自上次启动数据库以来的所有数据。

    常见的数据库管理系统由存储引擎和外部的“wrapper”构成。存储引擎是数据库的核心,其本质是一棵查找树(B树、B+树、LSM树),通过查找树可以高效地完成数据读写等数据库基本功能。外部的“wrapper”负责解析命令、查询规划、用户认证等功能。

    要查看mysql的存储引擎,可以在MySQL控制台输入show engines。下图所示列出了MySQL使用的存储引擎,可见其中并没有thphd提到的“leveldb/myrocks”

    事实上,MySQL最常用的存储引擎的是InnoDB和MyISAM。InnoDB是芬兰公司Innobase在2005年开发的一款存储引擎,MyISAM是MySQL团队基于IBM ISAM开发的存储引擎。而LevelDB是谷歌公司在2011年发布的一款嵌入式数据库,和MySQL风马牛不相及。

    再进一步,thphd对LevelDB存储特性的分析,也是完全错误的:

    leveldb极度依赖底层磁盘的顺序写入特性,如果底层磁盘(这个例子中是虚拟磁盘)不完全是顺序写入的(例如为了性能开启写入缓存),那么强行重启就会导致丢失最近写入的几个ldb文件,而leveldb在这种故障模式下完全无法recover(因为作者假定磁盘是强顺序写入的),使得强行重启有一定几率会导致丢失自上次启动数据库以来的所有数据。

    从技术角度说,leveldb并不依赖底层磁盘的写入特性。确实,LevelDB对底层存储设备做了“顺序写入速度大于随机写入速度”的假设,这是为了优化写入性能。这种实现叫做LSM树(Log Structured Merge Tree,日志结构合并树),而不是thphd所说的B+树。好了,这里thphd又犯了一个知识性错误。

    LSM树会把对数据的修改变化缓存在内存中,达到一定的大小限制后,将这些变化批量写入磁盘。确实,在LSM树把数据写入磁盘之前,断电会导致数据丢失,然而LevelDB中数据缓存-写入的间隔非常短,仅为几百毫秒。换句话说,如果你在1秒的时间内,向LevelDB写入数据然后断电,那么这1秒内写入的数据确实会丢失,但是只要超过1秒,数据就会永久写入磁盘,不管怎么断电都不会影响数据,除非磁盘本身损坏。

    再退一步说,LevelDB的作者是谷歌首席程序员Jeffrey Dean,并且在开发过程中得到了谷歌的大力支持。就算你对我或thphd说的一切表示怀疑,你应该可以相信谷歌顶级程序员的实力——LevelDB经过了无数苛刻环境的考验,重启电脑并不会丢失大半年的数据,否则谷歌首席程序员就不要混了。

    至于看了《对养猫君对葱爆的分析的分析》信以为真的网友,这不是大家的错,毕竟术业有专攻,不能要求每个人都是IT专家。但是贵站的前站长thphd暗示自己是“IT从业人士”,却发表这样一篇错误百出的文章,我想只有两种可能:要么是 1) 拉大旗扯虎皮,用专业名词忽悠外行,证明自己对“葱爆”的原因推测正确,进而达到污蔑其它网站的目的。要么就是 2) 没有基本的网络常识,被抓迟早的事。

    相关资料:

    [1] MySQL存储引擎:https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html

    [2] MySQL磁盘满的行为:https://dev.mysql.com/doc/refman/8.0/en/full-disk.html

    [3] LevelDB:https://github.com/google/leveldb

    [4] LSM-tree: https://en.wikipedia.org/wiki/Log-structured_merge-tree

  32. 差生文具多   在小组 国家局域网研究所 回复文章

    不建议日常使用chrome绿色版

    可以尝试一下Chromium浏览器(和Chromium内核是不同的东西),这个是从Chromium编译来的浏览器,去掉了Chrome的自动更新和遥测,可以一试。

  33. 差生文具多   在小组 国家局域网研究所 发表文章

    《连线》杂志报道rust:接管技术的安全编程语言

    https://www.wired.com/story/rust-secure-programming-language-memory-safe/

    Rust 被称为“内存安全”语言,因为它旨在使程序不可能意外地从计算机内存中提取意外数据。当程序员使用不具备此属性的强大语言(包括 C 和 C++)时,他们必须仔细检查程序将请求哪些数据以及如何请求的参数——即使是最熟练和最有经验的开发人员也会偶尔执行这项任务拙劣。通过使用 Rust 编写新软件,即使是业余程序员也可以确信他们没有在代码中引入任何内存安全漏洞。

    很少见到大众媒体报道这样专业的领域。

  34. 差生文具多   在小组 2047 回复文章

    为什么tor在safer级别下会在hcaptcha卡CPU?

    可能是hcaptcha的bug,建议打开浏览器调试器看看发生了什么。

    浏览器里一个页面对应一个浏览器渲染线程,就算是多核CPU也是一样的。如果js陷入死循环,或者长IO没有异步操作,就会阻塞渲染线程,导致页面卡死。

  35. 差生文具多   在小组 2047 回复文章

    为什么tor在safer级别下会在hcaptcha卡CPU?

    我用safer,没有发现这样的问题。

    可能是你的电脑问题。查一下有没有中毒和tor安装包的数字签名

  36. 差生文具多   在小组 2047 发表文章

    马伯庸:穿越回古代怎么写好一份劝进表

    劝进是一个政治举动,写劝进表则是一门技术活儿。

    “劝进”这个词,本意是劝勉、促进,诸如“上下同心,劝进农业”、“砥砺藩屏,劝进忠信”等等,偶尔也会用在劝人喝酒吃药上,像宋代皇帝阅完兵,要赏管军的三盏劝进酒,即是这种用法。

    可一旦这个词出现在政治语境里,气氛立刻就变得不一样了,因为它往往预示着皇权更迭——在古代政治里面,没有比这更严肃的事情了。

    皇权更迭有很多形式,具体来讲,大部分古代“劝进”会发生在这样一种场景下:有人想当皇帝了,但慑于某种规矩和舆论,不好自己主动开口。这时就会有一班贤臣急主公之所急,站出来论证其称帝的举动是多么正确合理,敦促他尽快践祚。这种举动,叫做“劝进”,所形成的正式文本,则被称为“劝进表”。

    再接下来,劝主要反复辞让,表示谦逊不受,贤臣们要反复坚持劝进,来回三次。走完这个流程,就可以称帝了。

    “劝进表”的性价比相当高。它的政治风险很小,因为那些有“劝进”需求的人,本身实力已足够强大,距离皇位只差个名分而已,你押错宝拍错马屁的概率很低;同时收益却很大,一纸劝进表交上去,就算不是嫡系出身,也能摇身变成从龙之臣,坐收拥立之功。

    西晋灭亡之后,好多人纷纷上劝进书给逃去了南边的晋王司马睿,请他称帝。司马睿从善如流,立刻建都改元。登基之后,司马睿要做的第一件事,就是“赐诸吏投刺劝进者加位一等,百姓投刺者赐司徒吏”。好家伙,所有劝进过的人,甭管亲疏,人人都可以进位一等,就算你是平头百姓,也能成为司徒吏——这是一种低级散官,在晋代已沦为荣衔,但好歹算体制内,比白身强——可见“劝进”的收益有多大。

    成本才多少?一份名刺,一卷劝进表而已。

    顺便说一句,司马睿这次决定赏赐的“劝进党”有多少人呢?《晋书熊远传》里记载得清楚:“凡二十余万”。怪不得司马睿刚说出这个想法,旁边号称“忠公”的名臣熊远吓得脸都绿了,皇上啊,劝进是好事,可您也不能这么慷慨啊!

    听完这个成功案例之后,我想读者朋友们应该已经摩拳擦掌、跃跃欲试了吧?万一有机会穿越,这可是迅速上位的大好良机。

    那么咱们进入实操阶段,仔细研究一下,该如何撰写一份合格的劝进表。

    其实劝进表的写法并无一定之规,可长可短,可简可繁,但其要旨不变。写作重点可以总结为“一层窗户纸、两个问题、三个挟持、四个方法和五个凭恃。”

    一层窗户纸,是指劝进的本质。要知道,劝进表名为“劝进”,绝不是劝进。人家不用你劝,人家早就想称帝了,就是等你递个话儿而已。所以写作劝进表时,千万要吃透这一层深意,不要真以为劝主是谦虚,但同时也不要戳破这层窗户纸,反而要设法加厚。

    后周太祖郭威当年辅佐后汉,听闻契丹南下,连忙带兵北上,走到澶州地界,士兵们起哄说要拥立他为帝。郭威勉为其难地带兵回到汴梁,合城大震。那些文武百官、内外将帅、藩臣郡守纷纷上表劝进,场面十分热烈。有个御营的步军小校看着眼馋,喝醉了酒到处跟人说:“昨澶州马军扶策,今步军亦欲扶策。”

    “扶策”就是簇拥之意。郭威听说以后大怒,你身为御营军官,说这话什么意思?是暗示这事儿是我主动干的喽?立刻派虞候去抓人,当天就给宰了。其实小校只是想表个忠心罢了,可说的话太露骨,把窗户纸给戳破了。

    跟他相比,唐初的裴寂就高明太多了。

    隋恭帝逊位之时,群臣劝进李渊登基,李渊也是坚决不接受,而且看那架势,不是假意,而是真心。裴寂一脚踹进门去,说你咋不接受呢?李渊不搭理他。裴寂大怒:“桀、纣之亡,亦各有子,未闻汤、武臣辅之,可为龟镜,无所疑也。寂之茅土、大位,皆受之于唐,陛下不为唐帝,臣当去官耳。”

    夏桀、商纣都是有儿子的,我可没听说过成汤、周武他们不造反,愿意跑去辅佐他们。陛下你咋不学学他们呢?我有今天的地位和成就,都是您给的。您要是不登基当皇上,人家,人家,人家就不要做这个破官啦!

    这段话说的,明里咄咄逼人言辞冒犯,暗里简直就是在打滚卖萌。仔细揣摩其中问句,无不暗合“一层窗户纸”的原则。所以李渊非但没杀他,反而乖乖去参加禅让仪式了。参加完以后,还要表扬裴寂:“使我至此,公之力也。”——看到没有,这是在表扬裴寂这层窗户纸糊得好。

    御营小校那句话,举个例子,是在冲领导喊:“领导你收了别人的礼,我也想给您送。” 领导想收礼吗?想啊,但谁让你这兔崽子喊出来的?而裴寂的做法则是类似于“领导我要批评你,你太不注意休息了!” 他说得越愤慨,领导觉得越舒心。

    一层窗户纸定准以后,接下来你还要考虑两个选择。

    第一,选择正确的人和时机。

    从广义上来说,只要是皇权更迭,你上书表忠心,都可以算“劝进”。但如果人家是正常的父死子继,顺理成章的事,你跑来捧场也不是不行,但没那么多好处——劝进不求好处,还劝个什么劲?

    平日里锦上添花,哪如这一夜雪中送炭。你要找的,是那些有称帝迫切需求、同时按常理又满足不了的人。有人想改朝换代了——比如王莽、曹丕、刘裕;或者本不在继承顺位的人正好赶巧了——比如司马睿、赵构;甚至有人本身就是继承人,但非想强行提前上位——比如李亨、查尔斯……哎,后一个不算。

    只有选到这样的人,你上书劝进,才有足够的收益。

    而且光选对了人还不行,还要把握好时机。

    明末之时,清兵进了北京城。滞留在北京的前明忠臣们忙不迭地去武英殿觐见多尔衮,以示效忠之意。其中有个叫王鳌的侍郎,回来满脸喜色,跟同僚讲这个多尔衮原来是摄政王。在座之人都是饱读诗书之辈,一听就明白了,历朝历代哪个摄政王不想当皇上啊?咱们可得赶紧劝进,别错过从龙的好时机。

    于是这几个人赶紧写了一封劝进表,然后写上自己的大名:骆养性、沈维炳、王鳌永、金之俊。谁知写完以后,多尔衮却不见客。他们只好找到内院大学士范文程,恭恭敬敬把劝进表交上去。

    范文程一看,大笑着说了一句打脸的话:“此未是皇帝,吾国皇帝,去岁已登极矣,何劝进之有?”

    送对了人,却送错了时机。这一干大明纯臣,只好一脸黑线地退了回去。

    有时候甚至你送对人送对时机,运气不好,也不成。

    十六国那会儿,后赵有个技术官僚叫成公,为暴君石虎造了一个新型虐人工具,叫“庭燎”,上头是个大盘子,里面点了火油,下头绑人,靠热传导活活烤死,和炮烙原理差不多。石虎很喜欢这个设计,就把它搁到大殿里了欣赏。正好他正在谋篡皇位,一群手下商量着去劝进。

    这些手下选对了人,劝进的时机也很合适,可他们刚走进殿门,那尊庭燎台不知为啥突然塌了,上头盘里的火油四射,当场烧死七个人。

    你说这是不是倒霉催的。

    第二,选择正确的劝进方式。

    除了选对人和时机之外,你还要选择正确的劝进方式,简称“活儿细”。

    刘邦平定了天下以后,身份一直还是汉王。一群老兄弟急吼吼地要劝进,说我们要刘哥哥做鸟皇帝。刘邦扭扭捏捏地回答:“吾闻帝贤者有也,空言虚语,非所守也,吾不敢当帝位。” 老兄弟们立刻嚷嚷起来:“大王起微细,诛暴逆,平定四海——说到这段,听着都还算像话,可往下听味道就不对了——有功者辄裂地而封为王侯。大王不尊号,皆疑不信。臣等以死守之。”

    我们跟您一起打天下,现在终于都有资格裂土封疆了。你坚持不当皇帝,难道是打算不分我们好处了?

    这话要是搁到后面皇权极重的几朝,功劳再大也得砍头。劝进哪有这么劝的?活儿太糙了吧?

    不过汉初的情况不太一样。那会儿皇权草创不久,包括“劝进”在内的各种规矩还未成熟。严格来说,刘邦遭遇的劝进,是有皇帝以来的头一回

    何况那一群功臣出身草莽,喝醉了酒,敢在宫殿里拔剑击柱,简直没个体统,还得等叔孙通出手,才算教会他们分出君臣礼仪。指望他们跟后世劝进者那么文辞细腻,不太现实,所以老兄弟们的活儿糙点,可以理解。

    当然,后来那些裂土封建的异姓王也付出了代价,说不定与这次粗糙的劝进也有点关系。

    等到两百年以后,到了王莽篡汉的时候,政治制度进化成熟,劝进这事就显得有技术含量多了。

    元始五年,武功县在水井里发现了一块白石,上圆下方,上面刻着一行字:“告安汉公莽为皇帝。” 从此以后,各地如梦初醒,纷纷发现各种神异符谶,无一例外,都写着类似坚决拥护安汉公王莽登基的口号。

    当时有个叫哀章的梓潼大学生,在长安读书。他看到这一幕献祥瑞的奇景,决定也干点什么。哀章脑子灵活,胆子不小,弄了两个铜盒子,一个起名叫“天帝行玺金匮图’,另外一个叫“赤帝行玺刘邦传予黄帝金策书”。

    按照五德终始说,汉初为水德,后来改为土德,到了西汉末年,王莽的好基友刘向又给改成了火德。火色尚赤,奉赤帝,而王莽自称是黄帝直系后人。这劝进书的名字,一看就知道什么意思。在匮里,哀章直截了当写了“王莽为真天子,皇太后如天命”的字样。

    光有金匮还不行,哀章还特意换了一身黄衣服,冒充神使跑到高祖太庙里去嚷嚷。

    谁都知道这是假的,可王莽就差临门一脚,这次劝进可谓适逢其会。王莽立刻赶到高祖太庙,坐在刘邦快要压不住的棺材板上,把这两个金匮郑重其事接过去,转头就上书太后:“您看,老天爷非让我代汉,我不敢不从啊。”

    因为这次漂亮的劝进助攻,哀章被封为美新公,一跃成为新莽四辅之一,可谓一步登天。(严格来说,那会儿虽有劝进之实,却还没有劝进这个专有名词。)

    可见选择正确的劝进方式,是多么重要。

    好,现在劝进表的前期准备做完了,接下来我们就要进入实际操作环节。在动笔之前,请问自己两个问题。

    一个是Why-为什么皇帝要换人?

    一个是Who-凭什么换你?

    这是将来天下人都会问的问题。能答出这两个提问,一封劝进表基本就算是完整了。

    先说说Why。

    根据“一层窗户纸”的原则,你已经知道了,要劝进的对象想当皇帝,但不能明着说。Why的意义就在于,你要替他找出一个冠冕堂皇的客观理由,甚至需要提出一套理论,来论证这届皇帝已经不成了,该换了。

    寻找这种理由的方式,可以分成“三个挟持”。

    第一种,叫做挟天自重。

    要给劝进表戴一顶大大的帽子,先把天道义理、命数气运、历史规律等大词儿祭出来,站稳了大义立场,然后再跟自己的私货紧紧绑定,无往而不利。

    比较简单的做法,是展现一条波形图,告诉大家天眷是时刻在变化中的,时有波峰,时有波谷。

    比如南朝宋群臣向刘义隆劝进表的开头,就很简洁地铺排了二十个字:“否泰相革,数穷则变,天道所以不謟,卜世所以灵长。” 高屋建瓴地从哲学角度,揭示了天道规律。潜台词是,天都时常变化,你说皇帝变不变?

    如果觉得说服力不够,可以把这个道理做得更复杂一点,让天道和皇权之间建立起一个函数关系,一者变,另外一个也会跟着变。

    比如谢朓给南齐明帝写的劝进表,开头就列了这么一个函数:“时乘在御,必待先天之业,神化为皇,乃叶应期之运。” 把皇帝和老天爷的关系做了一个详细阐释。

    当然,你如果数学好,又不嫌麻烦,还可以设定一套更复杂的理论。

    比如以苏林给曹丕写的劝进表为例,开篇就是这么写的:“天有十二次以为分野,王公之国,各有所属,周在鹑火,魏在大梁。岁星行历凡十二次,所在国天子受命,诸侯以封。”

    这个十二次是岁星纪年法,简单来说,就是把天空分成十二个区域,岁星运转到哪一个区域,会有一个特定的名称,称十二次。苏林的意思是,每一次,都对应一个朝代的命运。比如周代对应鹑火,每次大事比如文王受命、武王伐纣,其年都是岁在鹑火。而魏对应的是大梁,从曹操讨黄巾开始,每次和魏国有关的大事,都是岁在大梁。

    接下来,他在劝进表里用了几百字,详细阐述了这个理论,然后话锋一转,说“魏以改制天下,与时协矣。”

    这是很高明的做法,先建起一套天命算法,不提曹魏,咱们先算大周。大周得国最正,算法无可辩驳,等到你接受了这个设定,再把曹魏代入公式一算,哎哟,大魏代汉也成立,真的是天命所归哎。

    还有比苏林更不怕麻烦的。

    东晋末年,刘裕筹划登基,各地官员纷纷劝进。当时的太史令——也就是天文台长——骆达在自己的劝进表里,甚至讲了一个数学故事。

    话说有个冀州的道士,叫释法称,跟他的弟子说,江东有个姓刘的将军,是汉室后人,我给了他三十二块玉璧,还有一块镇金饼,这是刘氏的命数。汉代从建武到建安,一共一百九十六年,曹魏从黄初到咸熙,一共四十六年;晋代从泰始到今天,一共一百五十六年,这三代从兴起到禅让的年份,里面都有个六字哎。

    这个算法的核心意思是:当每一个朝代的年龄里含六这个数字时,就有可能会发生改朝换代。

    这是典型的凑数,可刘裕偏偏就信这个。别人上表,他还有点扭捏,骆达这一份递过来,刘裕立刻大为满意,大笔批道:“六六六。”

    讽刺的是,刘裕没想到。等到刘宋末年,权臣萧道成打算夺位之时,一个叫陈文建的官员跑过来,又把释法称的故事又讲了一遍,还给续了一段:“刘宋从建国到今天,恰好六十年,里面也有个六,六始六终,看来齐王您果然是上膺天命了。

    嘿,始作俑者,其无后乎,真是太六了。

    第二种,叫做挟贤自重。

    这种方式不用麻烦老天,需要请出几位先贤。你需要把古代那些改朝换代的例子罗列一遍,证明上古大贤们也是这么干的,他们摸得,您怎么就摸不得了?

    苏林的同事辛毗在劝进表里就是这么写的:“臣等以为天命不可稽,神器不可黩,昔周武中流有白鱼之应,不待济而大号以建,舜受禅大麓,桑阴未移,而已陟帝位,所以祗承天命者,若此之速也,故无固让之义,不以守节为贵,必信於神灵,而符合於天地也。”

    白鱼之应,是说周武王有一次乘船渡河,一条白鱼跳入舟中。商以白为贵,白鱼入舟,恰好是周代殷商的征兆。受禅大麓,是指尧有一次指派舜去一片林麓,适逢大雨,舜躲在一棵巨大的桑树之下,因此没有迷路,尧遂有了禅让之意。有大舜、姬发这几位古人来陪绑,曹丕代汉,也就不算啥事儿了。

    魏臣们上的另外一本劝进表说得更直白:“有唐世衰,天命在虞,虞氏世衰,天命在夏;然则天地之灵,历数之运,去就之符,惟德所在。” 看看,尧舜禹三代都是衰兴接替,可见皇帝轮流做,今年到我家。

    关于这个手法,还有一个有趣的例子。靖康之耻时,赵构泥马渡江,紧锣密鼓地准备登基事宜。可是徽、钦二帝还在,他的继承顺位又不高,法理上有点说不通。这时有人适时出来劝进,是这么说的:“献公之子九人,惟重耳之独在;汉家之厄十世,宜光武之中兴。”

    这两个典故用得非常巧妙。晋献公一共九个儿子,只有重耳及时跑出去幸存下来,用这个典故,既低调地讲明赵构的处境,又把这段窘事化为赞颂;而把赵构比成光武,同样是承认了宋室失去北方的事实,期待他能和刘秀一样,再次中兴汉统。而且为了对齐字数,特意不提西汉十二帝,改说十世——从刘邦到孺子帝刘婴,恰好是十代人。

    这两句话是出自元佑孟太后的劝进表,不过她只是署名,代笔的人是汪彦章。这个用典技巧,可是太高明了。

    第三种,叫做挟时自重。

    除了上谈天文、纵论历史之外,劝进表还得接地气,需要从时政角度谈谈登基的必要性。毕竟前两者有点虚,只有现实才是最能引起读者共鸣的东西,以此为论据,说服力会极有质感。

    如果此时正逢乱世或乱世刚结束,那么就要极力痛陈天下之惨,抑到极致,然后话锋一转,说如今亟需一位明主拨乱反正,解万民于倒悬云云。

    司马睿南逃之时,北方已是神州陆沉、中原凌夷。王导和纪瞻前来劝进,一上来就挑明了这个状况,先抑后扬:“二帝失御,宗庙虚废,神器去晋,于今二载,梓宫未殡,人神失御。陛下膺录受图,特天所授。使六合革面,遐荒来庭,宗庙既建,神主复安。”

    煌煌正言,连续用“失御”、“虚废”、“未殡”几个词,把气氛抑至最低,然后陡然拔高,强调天子即位,不为私欲,而是为了再建宗庙,让神主复安,一抑一扬之间,力度顿生。

    说白了一句话,让你当皇帝不是为了爽,是因为有正事要你做。

    顺便说一句,纪瞻这个人,在劝进表的历史里值得一书。因为司马睿当时惊魂未定,对帝位还不是那么热心。王导和纪瞻劝了半天,连龙椅都准备好了,司马睿还是游疑不决,让殿中将军韩绩把御座给搬开。韩绩刚要动手,纪瞻一声大喝:“咱们皇上的座位,那是上应星宿,敢乱动者斩!” 韩绩吓得不敢近前不说,连司马睿都不敢吭声了——劝进劝成这样,真是一景。

    如果世道相对没那么差,这话该怎么说才好?也有办法,把聚焦点缩到具体某一个坏人身上。

    南朝刘宋之时,太子刘邵弑杀了父亲宋文帝刘义隆,天下耸动。刘义隆的第三子——即后来的孝武皇帝刘骏起兵讨伐。叔父刘义恭因为被怀疑勾结刘骏,被刘邵一口气杀了十二个儿子。刘义恭大怒,跑出去给刘骏写了一封劝进表:“今罪逆无亲,恶盈衅满,阻兵安忍,戮善崇奸,履地戴天,毕命俄顷,宜早定尊号,以固社稷。”

    这里的“罪逆”,即指太子刘邵。刘义恭痛斥这个兔崽子恶贯满盈,早晚得死,您要是做了他,那登基就是顺理成章的事儿了。

    可如果世道本来就挺太平,那就更简单了。乱世需要明君,那盛世更需要明君嘛。

    有一篇劝司马昭加九锡的劝进表,很充分体现出了这“盛世需明君”的思路:“况自先相国以来,世有明德,翼辅魏室以绥天下,朝无阙政,民无谤言。” ——这是夸奖司马懿一手缔造的盛世,然后戏肉来了——“明公宜承圣旨,受兹介福,允当天人。元功盛勋光光如彼,国士嘉祚巍巍如此,内外协同,靡愆靡违。” 这是夸司马昭是个好人,周围的手下也都是国士,可谓人才济济,内外用心。

    在这层层铺垫之下,作者逐渐把文章推向高潮,劝进表在最后如此写道:“今大魏之德光于唐虞,明公盛勋超于桓文。然后临沧州而谢支伯,登箕山而揖许由,岂不盛乎!”

    许由、支伯是尧帝时代的两位贤士,尧曾经考虑过把位置禅让给他们,但两者皆不受。这是拐弯抹角地把司马昭捧到了三代的高度,末尾四字点题:这个时代,岂不就是盛世了吗?

    这篇劝进表写得相当有水准,言辞雅驯,典故精详,文笔可称得上“清壮”二字,构思也十分巧妙。它的篇名叫做《为郑冲劝晋王笺》,作者叫阮籍。

    等等,竹林七贤里的那个阮籍?他不是最讨厌司马氏吗?怎么会写这么一篇舔司马昭的文?

    原来这事儿和一群拖延症患者还有关系。

    大魏朝廷准备封司马昭为晋王,加九锡。这是一件大事,按照标准流程,司马昭要表示辞让,然后诸位公卿将校联名上一份劝进表,劝他接受,然后司马昭才勉为其难地同意。

    可眼看交劝进表的死线到了,大家碰头一问,发现谁也没写,都指望别人准备呢。这可麻烦了,没有劝进表,辞让的戏就没法演了,你总不能让司马昭学拿破仑,自己去抢王冠吧?

    司空郑冲急了,急急忙忙派人杀到阮籍府上,催促他速成一篇劝进表,好应付作业。使者到府上一看,阮籍喝得酩酊大醉,正趴在书案上呼呼大睡。使者推醒他,说明来意。阮籍到底是天才,一挥而就,书成此篇,连改都不用改,时人誉为神笔。

    装醉是阮籍的成名绝技。钟会每次问他政见,他都故意喝醉不答;司马昭想找阮籍联姻,他敢连续装醉了一个多月。这次晋王受封,恐怕阮籍也是想故伎重演,把劝进的风头避过去。可惜人算不如天算,没料到满朝文武这么不靠谱,不写作业还则罢了,还找他来代笔。

    阮籍不是刘伶那种狂放,也没嵇康那么不羁,面对百官催稿实在推却不过,只好勉强写下了这么一篇算是人生污点的劝进表。据说阮籍写完是篇不久便即离世了,大概是心里觉得特别窝火吧。

    不过阮籍也做出了文人式的反击,在劝进表里埋了一枚小小的彩蛋。在这篇表的末尾,上承“岂不盛乎”,他接了这么一句话:“至公至平,谁与为邻!何必勤勤小让也哉?” ——公指公义,平指清平,都是经常用来修饰盛世的词。

    这句话的意思是,在您的治政之下,国家的公义和清平极致到简直没朋友,何必天天絮叨辞让这点小破事啊?

    这是句恭维话,可怎么听都像是逼急了的反讽,我一朋友跟家人吵架,他妈就爱说“是是是,全世界就你最明白。” 和这句话的味道差不多。所以我觉得阮籍这是反话正说,把你夸到了极致,才显得十足讽刺。这也算是小小报复吧。

    扯远了,咱们还是回到劝进表上来。

    总之,挟时自重的意思,是要论述紧贴于时事,无论是乱世还是盛世,都要引申到“时代亟需明主”这一个核心上。

    事实上,大部分劝进表里,很少孤立使用一种挟持,往往三者并用。先说一段历史规律,再引一段前朝故事,最后强调在这个关键的历史转折时期,实在太需要一位皇帝了。无论天道也罢,先贤也罢,时局也罢,其实就为证明三句话:皇上可以换;皇帝之前换过;所以皇上现在也需要换。

    这么写,文章看起来花团锦簇,逻辑关系层层递进,自然就有说服力了。

    好,接下来我们来说第二个问题:Who。

    时代需要新君,没问题,但凭什么是他?怎么不是别人?你选择劝进的那位,有什么独到的优势?

    劝进表里,必须得提供一个或几个理由,证明你的劝主实至名归。

    这事说简单也简单,说难也难,可以用“五个凭恃”来概括。

    第一个,凭恃功绩。

    如果你劝进的那一位,是自己打下来的江山。那就直接夸他的功绩就好了,反正干货多,不愁没词儿说。

    比如曹操加九锡那会儿,群臣卯足了劲夸他“明公奋身出命以徇其难,诛二袁篡盗之逆,灭黄巾贼乱之类,殄夷首逆,芟拨荒秽,沐浴霜露二十馀年,书契已来,未有若此功者。” 这都是实打实的业绩,不用编造,俯首皆是。

    宋武帝刘裕的战绩,同样丰富辉煌。劝进书里说“搜乘秣驷,夐入远疆,拓土三千,申威龙漠。追奔逐北,扬旌江濆,偏旅浮海,指日遄至。番禺之功,俘级万数,左里之捷,鱼溃鸟散。” 每一句都是有根有据的赞扬,不算夸张。

    以这些功绩为理由,怎么都说得过去了。

    第二个,凭恃血统。

    如果你劝进的那位,没有什么特别耀眼的功绩,也没关系。古代很看中血统出身,强调一下他的合法继承资格也很重要。

    比如刘备,半生颠沛流离,战绩委实不好吹捧,那劝进表里就不提那些糟心事,高高举起汉室宗亲这块大牌子:“伏惟大王出自孝景皇帝中山靖王之胄,本支百世,乾祇降祚,圣姿硕茂,神武在躬,仁覆积德,爱人好士,是以四方归心焉。”

    当时去汉未远,人心思旧。刘备一直靠“汉室宗亲”这块牌子宣传自己,占了一个兴复汉室的大义名分,效果卓著。群臣劝进的时候,自然腰杆也直得很,不愁没话可说。

    不过仔细研读这句话,你会发现,除了血统之外,刘备的优势还在于“仁覆积德,爱人好士”八个字。这就提醒了我们,血统这件事,不宜单独拿出来说,会被人讥笑是靠生殖器上位,一定要配以功勋或德行,血统既正,人品也好,多维度多角度进行称赞,这样才显得好看。

    稍微晚一点的西晋末年,刘琨对司马睿就是这么劝进的:“陛下道迈大宗,勋莫与二,且以亲以贤,义实兼之。” 这话说的太有水平了,十九个字,列举出了血统、功勋、德行、能力等一系列优势点,信息量巨大。

    安史之乱时,唐玄宗和太子李亨分开跑路,一个去了蜀中,一个去了灵武。裴冕、杜鸿渐、崔漪偷偷去劝进李亨:“主上厌勤大位,南幸蜀川,宗社神器,须有所归,天意人事,不可固违。”

    前头用“厌勤”、“南幸”四字,先不留痕迹地贬了玄宗一通,然后又强调说“宗社神器,须有所归”,这就是在强调血统,告诉李亨天下只有你最有资格继承皇位。这时李亨还有点犹豫,那三个人意识到光强调血统不够,李亨的底气不是很足,赶紧又补充了一句:“殿下藉累圣之资,有天下之表。元贞万国,二十余年,殷忧启圣,正在今日。”

    这句话,是有典故的。“殷忧启圣”四个字,正是出自咱们上面一个例子——刘琨给司马睿的《劝进表》,原文是:“或多难以固邦国,或殷忧以启圣明。” 前一句是“多难兴邦”这句成语的源头,指国家历经灾难可以更为坚强;后一句的意思是,人要时刻保持忧患意识,能够开启圣思与哲思。

    那三个人的意思是,殿下你不光血统好,本身悟性也不低,只要稍微多琢磨一下当前局势,不难成为圣贤。血统之外,你的资本可千万不能为零啊。

    李亨一高兴,立刻在灵武扬旗称帝。李隆基在蜀中听说这事时,已经来不及了,只好乖乖去做了太上皇。

    第三 ,凭恃符谶。

    谶读衬,符谶的全称叫做“符图谶纬”,指各种代表天道启示的书籍、图册乃至祥瑞象征。

    从两汉开始,这类书籍变得极为流行,翻阅当时人的著作,里面动辄引用大量名字诡异的书名。这些书名50%是同时代的人伪造,另外50%是前人伪造,从来没存在过。咱们在文章开头讲的那个哀章金匮书,其实就是符谶的一种。

    如果你要劝进的那位没什么功绩,血统也谈不上优势,没关系,就说他是老天爷钦定的呗,然后拿出一大堆符谶来证明。反正都是编造的,别人没地方去查证,我说什么就是什么,方便得很。

    这个做法和刚才“挟天自重”的区别在于。“挟天自重”不谈劝进,只谈天道规律,尽量保持客观立场;而“凭恃符谶”则要开宗明义,把劝主直接往各种超自然现象上联系。

    在具体做法,也有一个细致的分类,称之为“四个方法:背讲看猜”。

    第一个方法:背书名。

    曹丕篡汉之后,刘备称帝也紧锣密鼓地进行着。除了常年追随他的老干部们忙着劝进之外,还有以张爽、尹默、谯周为代表的一批文科生,也忙着打造劝进表。他们不是刘备嫡系,不好宣扬其功绩,就从符谶角度紧跟形势,背起了书名,节选一段:

    “谨案《洛书甄曜度》曰:’赤三日德昌,九世会备,合为帝际。’《洛书宝号命》曰:’天度帝道备称皇,以统握契,百成不败。’《洛书录运期》曰:’九侯七杰争命民炊骸,道路籍籍履人头,谁使主者玄且来。’《孝经钩命决录》曰:’帝三建九会备。’臣父群未亡时,言西南数有黄气,直立数丈,见来积年,时时有景云祥风,从璿玑下来应之,此为异瑞。又二十二年中,数有气如旗,从西竟东,中天而行。”

    大家不用看具体内容,只要体会一下这汹涌而来的书名和引号就好,因为说的都是毫无意义的废话。更不必去按书名去查索引,这些所谓“谶书”,不是作者信手原创,就是前人信手原创。

    这一时期的很多劝进表,都会罗列大量谶书引文,气势磅礴。虽然可信度很低,可对大多数人来说,文章的说服力不在实据和论证,而在句子的长度和气势。这么多神异玄幻的书名排比而出,很容易震慑人心,一不留神就跪了。

    你要是觉得背书名丢人,还有第二个方法,讲故事。

    早在曹丕称帝之前,最早劝进的人是左中郎将李伏。他写的那一份劝进表,可以说是所有劝进表中的异数,这次李伏没按照常规写法,而是讲了一个动人的故事:

    话说在建安十八年,曹操建魏国,封爵为公。李伏当时正好在汉中,那地方消息闭塞,传来传去,传成了曹操封魏王。有两个武都的术士叫李庶、姜合,对李伏说:消息肯定错了,曹操是魏公,不是魏王。因为我们俩见过符谶,上面说曹操的儿子曹丕,那才是天命所在。

    李伏不是这个专业的,没法判断这个说法的真伪,就把他们带到了专业人士张鲁的面前。张鲁问姜合:“你这句话从哪本符谶里看来的?”姜合面不改色地回答:“《孔子玉版》,这本书记载了一百世的皇帝次序。” 过了一个多月,忽然有一个人逃亡至汉中,把《孔子玉版》给默写出来了,内容和姜合说的一样。张鲁当时没吭声。

    后来等到曹操打到汉中,刘备在川中跃跃欲试。张鲁和李伏商议到底该怎么办,有人建议干脆投刘算了,张鲁突然大怒,说:“宁为魏公奴,不为刘备上客!” 后来果然投降曹操,被封镇南将军。李伏猜测,这肯定被那本孔子玉版所震慑,不敢违背天命的缘故。

    这故事是真是假,只有李伏知道,但可读性超高,而且寓意还特别细腻——张鲁为什么投降曹操?那是因为他相信了《孔子玉版》的预言;预言说什么?曹丕有天命。这岂不是说,曹操攻克汉中,归根到底要归功于有天命加持的曹丕么?

    更妙的是,故事里的几个当事人,姜合已死,李庶不知所踪,张鲁绝对不敢反驳没这事。李伏说什么,就是什么。

    那也许会有人问了,你怎么原来不讲,现在才说呢?

    李伏是这么解释的:“时未有宜,弗敢显言。殿下即位初年,祯祥众瑞,日月而至,有命自天,昭然著见。然圣德洞达,符表豫明,实乾坤挺庆,万国作孚。臣每庆贺,欲言合验;事君尽礼,人以为谄。”——就是说,时机没到,我不敢明说。再说您即位那年,各种祥瑞都出现了,很显然是天命所归,我如果凑上去说这个,怕别人嫌我谄媚。

    那你怎么现在又敢说了呢?

    李伏回答:“今洪泽被四表,灵恩格天地,海内翕习,殊方归服,兆应并集,以扬休命,始终允臧。臣不胜喜舞,谨具表通。”—陛下你太英明神武了,我抑制不住地欢喜,不得不把这个故事将给您听。

    看似每一段都是在解释这个故事和自己,其实每一段都是在捧曹丕。李老师你还怕别人嫌你谄媚啊?

    利用符谶的第三个方法,是看星星。

    古人极看重天文观测,深信星辰排列代表了天道意志以及人间福祸,和符谶之说密切相关。假如能够把天文观测记录用迷信的方式解读一下,赋予“劝进”以天意的合法性。

    “挟天自重”,那个天,是天道,是大而化之的概念,而这个“看星星”的天,指具体的天文现象。

    东晋末年,刘裕筹备登基称帝,陈留王虔嗣等二百七十人上表劝进。可惜其全文没留下来,不知这篇劝进表哪没写对,刘裕死活就是不肯通过。一群人发愁,嘀咕说这劝进只是走个过场而已,皇上怎么还认真起来了?这时站出一位天文台的老专家——太史令骆达,说:“我来吧。”

    骆达也不提功绩、也不说德行,对刘裕只字未体,而是给他看了长长的一串天文观测记录:有“太白昼见经天凡七”,有“五虹见于东方”,有“镇星、岁星、太白、荧惑聚于东井”,有“镇星入太微”,先后十几条记录,而且每一条记录后面,都有一个占字,表示这天象所代表的政治意义。比如看见太白经天,这是“人更主,异姓兴”,看见“黑龙四登于天”,这是“天子亡社稷,大人受命”,总之看啥都是改朝换代的预兆。

    然后骆达又列出一道数学题,这个前文已经讲过。总之刘裕被这一套气势磅礴的说辞彻底折服,欣然登基称帝。

    符谶劝进还有第四种方法,猜字谜。

    字谜是符谶学里的老桥段了,很多谶语预言,都是靠拆字来表达。比如“千里草,何青青”是个董字,“十日卜,不得生” 就是卓,合起来就是董卓药丸。比如“东海十八子,八井唤三军”,十八子是李,八井三军是个渊,合起来就是李渊二字。

    大唐亡于朱温以后,各地势力都开始蠢蠢欲动。蜀中的王建也颇有心思称帝,其妻弟周德权看准时机,便用字谜的形式劝进。他编造的那条谶语是:“李禧西王逢吉昌,土德兑兴丹莫当。”

    怎么解释呢?“李禧”指大唐已完;“西王”,是说西蜀会有人称王;这个“逢”字,和王建的名字构字法相近(谁也行啊?)土德是在西南方,兑按八卦方位,也是西方。“丹”是朱色,代表朱温,丹莫当就是朱温拦不住您。

    分析了这么一通,周德权这才进入正题:“愿稽合天命,仰膺宝鉴,使天地有主,人神有依。” ——总之您呐,赶紧当皇帝吧。

    这倒是没什么成本,就是太费嘴了,脑洞小一点都圆不回来……

    背书名、讲故事、看星星、猜字谜,只要掌握了这四种方法,那么“凭恃符谶”这条路就能走得很平顺,论证起劝主的天命所归,也就无往而不利了。

    当然,如果你对封建迷信不屑一顾,还有一招。

    第四点,凭恃德行。

    一个人可能没功绩,可能没血统,也可能懒得编符谶,但不可能没人品。人品是最容易赞扬的东西,只要用心,什么人都能找出一点闪光点,夸出花来。

    萧道成有一个侄子叫萧鸾,他先后废立萧昭业、萧昭文两兄弟,最后自立为帝,成为南齐的第五位帝王,为齐明帝。

    萧鸾既然要称帝,必然需要百官劝进。可是他的经历,实在没什么可称道的,这封劝进表不好写。好在百官找到一位大手,叫谢朓。此人文才奇高,和“大谢”谢灵运齐名,人称“小谢”。

    谢朓没有推辞,挥笔写成一篇劝进,其中是这么夸奖萧鸾个人的:

    “陛下文思体道,徇齐作圣。剪应龙於冀州,戮长蛇於沮水。荣光之瑞昭回,延喜之宝润色。天睠爰发,人谋咸赞。”

    啥?

    “文思体道,徇齐作圣”还算能理解,后面那两句怎么回事?剪应龙、戮长蛇,这不是玄幻小说主角才干的事吗?

    应龙是上古神兽,曾奉黄帝之命在冀州与蚩尤交战;长蛇是《山海》经里的一种怪兽,居住于大咸之山,身上长满了类似猪毛,叫声如鼓。沮水位于汉中以西,和传说中的大咸之山方位接近。这两个地方、两头神兽,似乎跟萧鸾没半点关系啊?

    其实是这么回事。

    萧鸾曾经担任过郢州、司州和豫州刺史,豫州理论上——注意,是理论上,因为那会儿中原不在南朝势力内,很多南朝行政地名只是沿用晋代名称,位置其实是在江南,叫做侨州侨郡——与冀州接壤,而沮水勉强算是被司州和郢州夹在中间。

    萧鸾历任的这些职位,很多都是与北魏对峙的分界线。谢朓连用了“应龙”和“长蛇”两个典故,通过地理关系,巧妙地联系上了他这些职位,暗示有守土御敌之功。

    费了这么一番心思,算是把萧鸾给夸起来了。虽然是牵强附会,但文辞漂亮,大家看了谁也不会说什么。

    接下来几句,就比较好理解了。

    “荣光之瑞昭回,延喜之宝润色。天睠爰发,人谋咸赞。”——昭回指光芒旋转,这都是陛下您要登基之前的吉兆,吉祥密集的光芒在闪耀旋转,延续如意的宝物也变得色泽温润。上天的眷顾落到了您的身上,所有人都发自内心地称赞这殊胜一幕。

    我看再唱下去,谢朓就得给萧鸾献哈达和酥油茶了。

    历史上还有一个特别会夸人、甚至夸得要吐的劝进大手。

    明末之际,有一个叫周钟的庶吉士,在大明治下郁郁不得志,便起了心思,要在大顺军这边谋个好出身。李自成进京以后,他就主动跑过去,为其撰写诏书,还上了一份劝进表。

    劝进表里有这么几句:““陛下问罪燕都,威行夷夏。吊民江左,泽及昆虫,比尧舜而多武功,迈汤武而无惭德。独夫授首,四海归心。伏念臣衰残无力,愿为放牧之牛。摩顶知恩,甘效识途之马。”

    文才很一般,但架不住这位口气夸张。听听,比尧舜而多武功,迈汤武而无惭德,都已经捧到这种高度了。历代劝进表那么多,很少有人敢这么比拟的。

    这份劝进表传到南明朝廷,惹来一阵怒骂,由此引发了著名的顺案,连累了周镳、雷演祚等一干名士,马士英、阮大铖二人又起朝争。打着打着,南京城就被清军攻破了……

    其实也怪他们不查,“比尧舜而多武功,迈汤武而无惭德”这两句话,并不是周钟原创,而是从旧文里扒出来的。

    靖康之难以后,金朝在旧宋领地搞起一个叫楚的短命政权,强令宋臣张邦昌登基。张邦昌自己不是很愿意,但总有帮闲文人却爱凑趣。有个叫颜博文的著名文人,上表祝贺登基,说了这么两句:“非汤武之干戈,同尧舜之禅让。”

    这两句话的催吐值太高了,传到南边时候,朝廷也是一片呕声。几百年后的周钟大概是觉得,他和颜博文的情况竟然非常相近,于是直接化用,至今读之仍令人胃中一阵悸动。

    如果你实在学不会谢朓的手段,又不愿意追随周钟、颜博文的足迹,也没关系,还有一招。

    第五,凭恃寿命。

    北魏皇室有个孩子,叫元恭,是拓跋弘的孙子,广陵惠王之子。这个孩子大概是中国历史上最谨慎消极的人物之一了。他入朝为官之后,看到京兆王元叉擅权,生怕自己被波及到,干脆躲进庙里装哑巴。

    这一装,就是八年没开口,死死宅在龙花寺里,不与外人来往。可就算如此,也没躲过去,到了孝庄帝年间,有人报告皇上,说他能说话却一直不说话,肯定是有谋反意图。元恭心想你特妈什么逻辑,可皇帝偏偏就信这个,吓得他赶紧离开京城。

    这一跑不得了,民间都纷纷传说,元恭好厉害呀,在龙花寺修闭口禅八年不言语,这么高的道行,将来肯定是要当天子呀。元恭心想,你们特妈什么逻辑啊!可皇帝笃信不疑,派人把他抓回京城来。

    好在他确实没有谋反行为,折腾了一段时间,给放了。等到孝庄帝去世,权臣尔朱世隆嫌新皇帝元晔不顺眼,决定换一个,找来找去,找到元恭这位“沉潜藏匿”的倒霉宗室,觉得这人适合做天子。元恭在心里大骂:“你们特么怎么看出来的?”

    尔朱世隆跑到他面前,气势汹汹地问:“你愿意当我的Master不?” 元恭憋了半天,只憋出四个字:“天何言哉?” 意思是老天爷怎么看?尔朱世隆一听就明白了,问别人怎么看,就是说自己已经同意了嘛。他立刻开始操办庆典,安排元晔禅让。

    禅让照例要上劝进表,可元恭这人吧,宅了八年连话都不说,让人怎么夸?群臣沉思良久,在劝进表里如此写道:“伏惟陛下运属千龄,智周万物,独昭系象,妙极天人,宝历有归,光宅攸属,而将安独善,不务兼济,灵命徘徊,幽明载伫。”

    你看,真没啥夸的了,一动不动也勉强能当成优点。不过这段赞扬很可疑,像“运属千龄”、“灵命徘徊”这样的描述,很容易让人联想到另外一种动物。

    其实元恭做皇帝还是相当有手段的,心智也属上乘,即位后着实有一番功绩。中国那么多傀儡皇帝,只有他一个被称为“圣主”,可惜这位“运属千龄”的圣主,只活到三十五岁,就被高欢指使人毒死了,未免有些可惜。

    这还算是会夸人,还有那种不太会夸人的例子,就更惨了。

    满清有个正蓝旗的宗室叫熙洽,在东北军里任张作相的副手。九一八事变后,他觉得这是复辟大清的好机会,投靠了日本人,托学者罗振玉去天津,呈给溥仪一份劝进表。

    “皇上圣鉴:敬陈者,臣熙洽跪。日本素知皇上德高恩重,久望皇上返吾祖发祥地满洲复位,以救苍生。为彼,臣树帜独立,将倾全力操练军队,扩充武器,在日本帝国信义资助下,先据有满洲,再图关内。此谓复兴之计,在此一举,亦是为臣期待二十年之时机,今日终将到来。”

    这劝进表写的吧,是真寒碜。看得出来,熙洽是真想夸溥仪,可真的没啥可夸的,溥仪退位才多大?琢磨了半天,他只好来一句“德高恩重”,没了。

    我一直挺奇怪,以罗振玉的才华,替他捎信的时候怎么没润色润色。

    总之吧,关于WHO这一部分,中心思想就是赞美,无论功绩、血统、符谶、人品还是命数,只要证明被劝进者优秀到是皇帝的不二人选,就算完成任务。

    当然,还有一点比较飘忽的要求,很难用公式去概括,但也很重要:你在写这些赞美时,一定要饱含深情,满载厚意,起码要达到“连爷爷您回来了”和“金将军我们支持你”的程度,最好把自己都能给感动了。

    正如沈蜅写给梁元帝萧绎的劝进表那样:“太阳不可以阙照,天地贞观,乾道不可以久愓,宝器存乎至重,介石慎於易差,黔首岂可以少选无君,宗祏岂可以一日无主。”

    或者内敛一点像群臣给刘义隆的劝进表:“臣等忝荷朝列,豫充将命,复集休明之运,再覩太平之业,行台至止,瞻望城阙,不胜喜悦鳬藻之情。”

    千言万语汇成一句话:我们不能没有你啊,皇上~~

    这份劝进表就完美了。

    以上就是劝进表的写作方法。必须要强调的是,无论是“两个问题”、“三个挟持”、“四个方法”还是“五个凭恃”,这些在劝进表中的位置都不固定,彼此也不是互斥选项。事实上,大部分劝进表都是数者并臻,面面俱到。谈天道的,也会说时政;夸功绩的,也会炫耀血统,只是在具体比例上有所不同罢了。

    如果大家要进阶学习的话,我推荐晋代刘琨的这篇《劝进表》。这是历代劝进的巅峰之作,文笔、结构、情绪俱是上佳,《文心雕龙》称赞其为“刘琨劝进,张骏自序,文致耿介,并陈事之美表也”,更被后人捧为比肩诸葛亮、岳飞的忠臣名篇。只要套用上面的作法去看,相信必有所裨益。

    不过若论千古奇文,刘琨这篇还是差一点,最精彩的一篇劝进表,竟是出自民国。

    准确地说,是民国四年。

    袁世凯大总统做腻了,想要登基称帝。为了制造舆论,他买通了很多社会团体摇旗呐喊,连乞丐和妓女也被组织起来,上街游行拥立。

    那时候京城青楼里有个叫做花元春的花魁,乃是顶尖名妓之一,与袁世凯的儿子袁克定相交颇多。

    花元春思及自己曾与大太子宵衣旰食、推心置腹,前逞管鲍之交,后效犬马之劳,如今有了这么大的机遇,不可不重视。她联络了另外一位名妓“小阿凤”以及总统府高参顾鳌,奔走串联,拉出一个规模颇大的妓女请愿团,也要拥戴大总统当皇帝,甚至也准备了一份劝进表。

    这份表的具体内容,已无从查考。网上有流传一份正文:“妓女等虽持皮肉生涯,也算商标性质。若援捐躯报国之条,自惭形秽;准诸以身发财之义,敢外生成。合亟披沥下枕劝进”。

    仔细揣摩的话,会发现前半段的口气像是第三人在描述评论,不像是劝进表里的自称。我查了一下,果然是误传。这其实是袁世凯和杨度的对话。当时袁世凯听说有妓女劝进团,又是高兴,又是疑惑,问杨度说以后称帝了,咱们怎么酬劳人家啊?杨度回答,妓女是做皮肉生涯的,凭肉身发财,你给她们题个字,就当是御用商标了。” 袁世凯想了想,没答应,毕竟太不成体统了。后人传播之时,误把两件事合并到了一块。

    但最后那八个字,我相信应该是出自劝进原文,因为那个口气,正是在对洪宪皇帝表忠心。

    “合亟披沥,下枕劝进。”

    “合亟”是公文用语,指“理应尽快”。“披沥”是披肝沥胆的简称,意为真心坦诚以待。合亟披沥,就是我迫不及待想要表白我的想法:

    下枕劝进。

    “下枕”二字妙极,既带旖旎不舍之情,又合大义决然之志。后接“劝进”,立意霎时高远起来。

    拳拳四字,耿耿忠心,洪宪一朝有此良谶宏谟,国祚绵长也就不足为奇了。

    2017/07/22

  37. 差生文具多   在小组 2047 回复文章

    【纽约时报政论】习近平避而不谈的两个口号说明了什么

    说实话对台开战风险很高。有人说习近平对台开战是为了获取政治资源,谋求任期,但是习近平更有可能是要做“千古一帝”,对台战争就是他历史留名的本钱。

  38. 差生文具多   在小组 2047 回复文章

    对于反贼来说运营商的光猫设置成桥接和路由哪个更安全?

    单说安全我觉得在插自己路由的情况下,两者一样的。因为插自己路由的目的,就是避免光猫看到本地网络做坏事(比如记录设备MAC上传之类的)。既然已经看不到本地网络,那么两者是一样的。

  39. 差生文具多   在小组 2047 回复文章

    对于反贼来说运营商的光猫设置成桥接和路由哪个更安全?

    建议改成桥接,把光猫当作网桥or交换机用。

    一方面我不太信任光猫的路由的安全性,所以我自己买了个路由加到它后面。另一方面国内大多数光猫的路由功能事实上非常垃圾,是运营商怕客户找事附赠的功能。如果是高速宽带,光猫做路由实际上是宽带的瓶颈,所以无论是出于安全性还是性能考虑,如果能设置路由器,就用桥接模式。

  40. 差生文具多   在小组 2047 回复文章

    对于反贼来说运营商的光猫设置成桥接和路由哪个更安全?

    如果认为光猫是可信设备,就设成路由模式,把它当路由器用。

    如果光猫不可信,就设成桥接,里面插个路由器用。

    当然我高度怀疑这种光猫的安全性,这东西很可能会收集本地网络信息并上传

  41. 差生文具多   在小组 2047 发表文章

    【依云's Blog】我所讨厌的网页行为

    原文: https://blog.lilydjwg.me/2022/8/18/annoying-webpage-behaviors.216433.html

    作者: 依云

    有些网页的行为通常不被视为 bug,甚至是故意为之,但很令人讨厌。这里记录一些我所讨厌的网页「特性」。它们被归为两类,要么导致某些场景下用不了,或者用着很不方便,要么很打扰人。

    可访问性问题

    忽视系统、浏览器设置,在浏览器使用浅色主题的情况下默认使用深色主题,或者在浅色主题下代码部分使用深色主题。反过来问题不大,因为我有DarkReader

    主体文本不支持选择和复制。选择和复制之后,用户能做很多事情,比如查生字、翻译、搜索相关主题。

    已访问链接与未访问链接显示没有差别。

    消除可交互元素(链接、按钮)的 outline。这个 outline 以前是虚线框,现在火狐改成了蓝色框,用于标识当前键盘交互的对象。

    搜索框不支持回车确认,必须换鼠标点击。

    位于文本框后的按钮不支持使用 Tab 键切换过去,并且 Tab 键在此文本框中也没有任何显著的作用。必须换鼠标点击。

    需要交互的元素不能被 vimium 插件识别为可点击。这大概是使用非交互元素来处理交互事件,甚至事件监听器都不在元素本身上。

    使用 JavaScript 实现原本可以直接用链接实现的内容(链接目标是某个 JavaScript 函数调用)。这导致我无法使用中键来在新标签页中打开。

    显著不同的内容没有独立的 URL。尤其见于一些单页应用(SPA)。要到达特定内容(比如加书签或者分享给别人),就只能记录先点哪里、再点哪里等。

    预设用户的屏幕大小,导致浏览器窗口过小的时候部分关键内容(如登录按钮)看不到、无法操作。

    交互元素没有无障碍标签。成堆的「未加标签 按钮」。

    通过 User-Agent 判断浏览器,并拒绝为某些 User-Agent 服务(但实际上去除这个限制之后,功能是完全没有问题的)。

    当没有带声音自动播放权限时,无声播放主体内容(而非等待用户操作使其获得权限)。说的就是 Bilibili。

    为大屏幕用户(如桌面用户)展示为手机屏幕设计的页面。这些页面中字体特别巨大,并且不能被浏览器缩放影响。交互元素上鼠标指针不改变为手状,甚至只支持触摸操作而不支持鼠标点击。

    悬浮于主内容之上的「在App中打开」。点名批评 imgur。它的按钮不光挡住图片,而且用户放大图片的时候它也被放大,挡住更多图片内容。

    不能禁用的图片懒加载,或者视频内容被移出画面、切换到后台就停止加载。点名批评 Telegram、维基百科。我等你加载呢,你非要我盯着看你加载浪费时间?现在网好,你赶紧给我加载好,进电梯或者地铁或者山洞了,我再慢慢看你的内容啊。

    视频内容被移出画面就停止播放。点名批评知乎。我让你播放你就给我播放。我不看视频,是因为视频画面没啥可看的,可是我听音频部分呀。

    覆盖浏览器的 Ctrl-F 查找快捷键,并不提供方案来避免覆盖。我就搜索当前页面,不要你的站内搜索功能。

    注册前请务必先阅读用户条款和规则,用户条款和规则页面需登录后才可访问。

    简体中文内容指定繁体中文的字体,或者添加繁体中文的标签。或者反过来。

    打扰用户

    在内容页面,任何会动的非主体内容,包括但不限于广告、内容推荐。形式可以是动态 GIF、滚动动画、视频等。用于首页渲染效果的背景动画和视频不算,作为主体内容者也不算。

    针对非音视频网站,自动或者非用户明确表达地(比如在用户点击不相关内容时)播放带音频的内容。

    消耗 CPU 的背景特效。如 canvas-nest。会让 CPU 很吵,也会浪费能源、加剧气候变化。

  42. 差生文具多   在小组 2047 回答问题

    在國外打一份普通工作能維持生計嗎?

    能。我所在的地区工作时长每周40小时,最低工资每月14000-17000人民币,物价比国内高10%-20%。如果一个人一无所长,只能领最低工资,只要不欠债、不沾黄赌毒,随便打份工就能过得很好。

  43. 差生文具多   在小组 2047 发表评论

    微博下拉浏览模式中,能否(如何)改成分页浏览或者逆时间浏览(先看某人第一条微博)?

    @食野之苹 #191274

    稍微改变一下后台查询指令就可以倒序查询,但是这需要程序员还有他们的产品经理愿意为用户开发这个功能。例如,按时间倒序(最新的在前面)查询某个用户所有微博的语句是:

    select * from weibos where user_id = $1 order by time desc;
    

    那么正序(最旧的在前面)就是

    select * from weibos where user_id = $1 order by time asc;
    

    换个指令就可以。

  44. 差生文具多   在小组 2047 回答问题

    微博下拉浏览模式中,能否(如何)改成分页浏览或者逆时间浏览(先看某人第一条微博)?

    倒序浏览确实技术上可以做到,不过大型网站很难做下拉改分页,下拉浏览流行的很大原因是下拉浏览方便适配移动端、后台开发方便(主要原因)。

    技术上的解释是这样的:假设新浪微博每页显示100条动态,那么你在APP上点击跳转到第10000页,数据库就需要扫描之前的所有数据,也就是100*10000条动态,然后才能返回你请求的那一页。在数据多的情况下,分页跳转对服务器压力很大,所以现在不少网站都改成了下拉加载。

    下拉加载的时候每加载一段,客户端只要向服务器发送上一页的游标即可(twitter就是这样的设计),服务器的压力是一个常数。因此这种方法可以用在大型网站上。

  45. 差生文具多   在小组 2047 回答问题

    往事不堪回首

  46. 差生文具多   在小组 2047 回复文章

    乌克兰数学家获菲尔兹奖,是政治正确还是确有成就?

    实在没法评价顶尖数学家的工作,因为普通人(或者了解一点数学的人)和评价数学前沿领域要求的能力差距太大,那些张口闭口政治正确的人,他们的脑子能看懂的也只有国籍这几个字了。

    不过我可以给出一个思路:去看一眼这个领域的数学家的推特,或者他们的blog,如果这个领域的数学家对此都没有什么意见,那么就是货真价实的成就。

  47. 差生文具多   在小组 2047 回答问题

    如果人类能够完美模拟所有快感,人类社会会怎样?

    人类社会会多出一种叫禁毒大队的东西

  48. 差生文具多   在小组 2047 回复文章

    【搬运】Rust | 批判性回顾

    这篇文章中提到一个很重要的Rust特性,对敏感软件(比如翻墙软件)的作者或许有帮助:

    Rust编译时会将源代码的完整路径打包进二进制文件(或许还有其它本机的上下文信息)。

    建议敏感软件的作者要么在虚拟环境下编译,要么只发布源码,直接发布二进制文件可能会导致你的身份泄露。如果必须匿名传送二进制文件,建议设置panic="abort",同时strip掉调试符号。

  49. 差生文具多   在小组 2047 发表文章

    【搬运】Rust | 批判性回顾

    原文:Rust: A Critical Retrospective:https://www.bunniestudios.com/blog/?p=6375

    翻译:机器之心/张汉东:mp.weixin.qq.com/s/eb_U2rirLjCqCLH8qs8k5Q

    译者注:说明:国内机器之心公众号对这篇文章进行了编译,发布了标题为《编写完10万行代码,我发了篇长文吐槽Rust》的一篇文章,我看了以后发现机器之心的这篇文章对原文原意的传达并不正确与完整,并且省略了很多对 Rust 开发者有帮助的关键细节,比如,作者如何防范 Rust 供应链攻击等,以及 Rust 超出作者预期的优点有哪些。所以特此全文翻译,供大家参考。当然,也要感谢机器之心对这篇文章的传播,让我有机会看到此文。

    由于在大流行期间我有几年无法旅行,所以我决定利用我新获得的时间并真正专注于 Rust。在编写了超过 10万行 Rust 代码之后,我想我开始对这门语言有了一种感觉,并且像每一个脾气暴躁的工程师一样,我已经形成了我自己的观点,因为这是互联网,所以我要分享。

    我学习 Rust 的原因是充实 Xobs 编写的 Xous[2] OS 的一部分。Xous 是一个用纯 Rust 编写的微内核消息传递操作系统。它的近亲可能是 QNX[3]。Xous[4] 是为轻量级(物联网/嵌入式规模)安全优先平台(如 Precursor[5] )编写的,支持 MMU 以实现硬件强制的页面级内存保护。

    在过去的一年里,我们设法为操作系统增加了很多功能:网络(TCP/UDP/DNS)、中间件图形抽象(用于模版和多语言文本)、存储(以加密的、看似可否认的数据库的形式,称为PDDB[6])、可信启动,以及具有自配置和密封(sealing)属性的密钥管理库。

    我们决定编写自己的操作系统而不是使用 SeL4、Tock、QNX 或 Linux 等现有实现的原因之一是我们想真正了解我们设备中的每一行代码在做什么。特别是对于 Linux,它的源代码库是如此庞大和动态,即使它是开源的,你也不可能审计内核中的每一行。代码更改的速度比任何人都可以审计的要快,除非是自己开发的。Xous的范围也很窄,只支持我们的平台,以尽可能地保持内核中不必要的复杂性。

    范围狭窄意味着我们还可以充分利用CPU运行在FPGA中[7]的优势。因此,Xous的目标是一个不寻常的RV32-IMAC配置:一个有MMU+AES扩展的配置。毕竟是2022年,而且晶体管很便宜:为什么我们所有的微控制器都不像桌面上的同类产品那样具有页级存储器保护功能?作为一个FPGA,也意味着我们有能力在硬件层面修复API错误,使内核更加精简和简化。这在通过抽象破坏(abstraction-busting)过程的工作中尤其重要,比如从RAM中挂起和恢复。但这都是另一篇文章的内容:这篇文章是关于Rust本身,以及它如何作为Xous的系统编程语言。

    Rust 的「卖点」

    在我们启动Xous的时候,我们看了大量的系统编程语言,Rust脱颖而出。尽管它的 "no-std "支持在当时还不成熟,但它是一种强类型、内存安全的语言,拥有良好的工具和一个蓬勃发展的生态系统。我个人是强类型语言的超级粉丝,内存安全不仅对系统编程有好处,它还能让优化器更好地生成代码,此外它还能让并发性不那么可怕。实际上,我希望Precursor有一个CPU,它对标记指针和内存能力有硬件支持,类似于在CHERI[8]上所做的,但在与做CHERI的团队讨论后,显然他们非常专注于使C语言变得更好,没有带宽来支持Rust(尽管这可能正在改变[9])。从总体上看,C语言对CHERI的需求远远大于Rust对CHERI的需求,所以这是一个公平的资源优先排序。然而,我是一个安全方面的粉丝,所以我仍然希望有一天,硬件强制的胖指针会进入Rust。

    虽然如此,我并不打算回到C语言阵营,只是为了踢一踢硬件改造的"轮胎",以弥补C语言的一个糟糕的方面。Rust 光鲜的手册还宣传它能够通过其严格的 「借用检查器」在错误发生之前就加以预防。此外,它的发布理念应该是为了避免我所说的 「Python的问题」:“如果你不主动跟上语言的最新版本,你的代码就会停止工作”。另外,与Python不同的是,Rust并非天生就不卫生,因为宣传的安装包的方式也不是错误的安装包的方式。与Python相反,在Python中,关于包的官方文档会引导你把它们添加到系统环境中,但却会被Python的“长老们”骂:“但你当然应该使用venv/virtualenv/conda/pipenv/...,大家都知道”。如果这个细节没有被归入官方教程的16章中的第12章[10],我对Python的体验会好得多。当有人取消发布一个流行的包时,Rust 也应该比 Node 更好地避免“哎呀,我删除了互联网”问题,至少如果你为你的包使用完全指定的语义版本。

    从长远来看,Xous背后的哲学是,最终它应该 "变得足够好",到那时我们就应该停止对它的操纵。我相信,工程师的使命就是最终把自己的工作搞好:系统应该变得足够稳定和牢固,以至于它 "只是能用",没有任何注意事项。在这一点上,任何额外的工程都只会增加错误或臃肿。Rust的 "稳定就是永恒 "的理念,以及承诺永远不破坏向后兼容的理念,从让Xous变得如此完美,以至于不再需要我这个工程师的角度来看,是非常一致的,从而使我能够将更多的时间和精力用于支持用户和他们的应用程序。

    Rust 欠打磨的地方

    网上已经有很多写给 Rust 的「情书」了,所以,我打算先列举我遇到的一些 Rust 的缺陷。

    语法中的噪音(Line Noise)

    这是一个肤浅的抱怨,但我发现 Rust 的语法很密集、很沉重,而且难以阅读,就像试图阅读附带噪音的UART输出一样:

    Trying::to_read::<&'a heavy>(syntax, |like| { this. can_be( maddening ) }).map(|_| ())?;
    

    用更通俗的话说。上面这句话的作用是在对象(实际上是结构体')Trying上调用一个名为to_read的方法,其类型注释为&heavy,生命周期为 'a,参数为 syntax,闭包的参数为like,在另一个名为 this 的结构体实例上调用can_be方法,参数为 maddening,任何非错误返回值都映射到Rust单元类型(),如果有错误,会被自动unwrap并返回给调用者。

    深呼吸。当然,我有一些地方是错的,但你会明白这种语法有多密集。

    在此基础上,你可以将宏和指令分层,而这些宏和指令不需要遵循Rust的其他语法规则。例如,如果你想条件编译代码,你可以使用一个指令,如:

    #[cfg(all(not(baremetal), any(feature = “hazmat”, feature = “debug_print”)))]
    

    这就是说,如果启用了 hazmat 或 debug_print 特性(feature),而且你不是在裸机上运行,就使用下面的代码块(我肯定也弄错了)。对我来说,这个语法最令人困惑的部分是使用单一的=来表示等价而不是赋值,因为,配置指令中的东西不是Rust代码。它就像一种独立的元语言,有一个你可以查询的键值对的字典。

    我甚至不打算讨论Rust宏的不可读性--即使我自己写了一些Rust宏,我也不得不承认,我觉得它们 "只是勉强能用",而且可能在它们的某个地方有“龙”(Bug)。这不是你在一门自称可靠的语言中应该有的感觉。是的,这是我的错,因为我不够聪明,无法解析语言的语法,但同时,我的生活中还有其他事情要做,比如构建硬件。

    无论如何,这是一个肤浅的抱怨。随着时间的流逝,我最终克服了学习曲线并变得更加自在,但这是一条艰难而陡峭的曲线。这部分是因为所有的 Rust 文档要么是用eli5 风格[11]编写的(形容文档写的非常简陋),要么你会看到一个正式的语法定义[12](从技术上讲,定义一个“feature”在那里,但没有用简单的英语概括)。

    要说明的是,我非常同情写好文档有多难,所以这不是在挖苦那些努力写出这么多优秀语言文档的人。我真的很欣赏文档生态系统的总体质量和丰富性。

    Rust只是在语法方面有一个陡峭的学习曲线(至少对我来说)。

    Rust 虽然强大,但并不简单

    Rust 很强大。我很欣赏它的标准库,它包含了 HashMaps、Vecs 和 Threads 等数据结构,既“美味”又令人上瘾。一旦我们在 Xous 中获得了 std 支持,就再回不去了。来自 C 和汇编的背景,Rust 的标准库感觉丰富且有用。我读过一些负面评价,说它缺乏一些功能,但就我的目的而言,它确实达到了最佳状态。

    话虽如此,我对 Rust std 库的依赖并没有在构建可审计的代码库方面带来任何好处。我以前对Linux的批评之一是:“天哪,内核的源代码包括红黑树的实现,怎么会有人来审计它呢”。

    现在,在写过操作系统之后,我对这些丰富的动态数据结构的重要性有了深刻的理解。然而,Xous 没有在其存储库中包含 HashMap 的实现这一事实并不意味着我们比 Linux 更简单:事实上,我们只是把一大堆代码“隐藏”了起来。仅仅是标准库的 "collection "部分就代表了大约1万多行源代码,而且复杂度非常高。

    因此,虽然 Rust 的 std 库允许 Xous 代码库专注于成为内核而不是其自己的标准库,但从构建最小攻击面、“完全由一个人可审计”代码库的角度来看,我认为我们对 Rust 的 std 库的依赖意味着我们在这个目标上失败了,尤其对于我们需要继续跟踪 Rust 的最新版本(我将在下一节中解释为什么我们必须这样做)来说。

    理想情况下,在某些时候,事情会 "稳定下来",我们可以把Rust 仓库分叉,然后说 "这是我们的攻击面,我们不打算改变它"。即便如此,Rust std 存储库的大小仍使 Xous 存储库相形见绌,这还不包括编译器本身的复杂性。

    Rust 还未完善

    接下来的这一点与Rust还不适合做完全可审计的内核的原因相吻合:语言还未完善。例如,在我们编写Xous的时候,引入了常量泛型(const generic)。在这之前,Rust没有处理大于32个元素的数组(Array)的能力。这种限制有点让人抓狂,即使在今天也有一些缺点,比如Default trait 无法初始化大于32个元素的数组。这种阻碍导致我们把许多东西限制在32个元素:例如,当我们在进程之间传递 SSID 扫描的结果时,该结构只为最多 32 个结果保留空间,因为去更大、更多通用结构是不值得的。这是直接驱动面向用户的功能的语言级别限制。

    另外,在编写Xous的过程中,像内联汇编(inline assembly)和工作空间(workspaces)这样的东西终于成熟了,这意味着我们需要回到过去,重新审视我们所做的一些“危险”的事情,使那些关键的几行用汇编编写的初始启动代码能够集成到我们的构建系统中。

    我经常问自己“我们什么时候才能离开 Rust 发布火车(火车式发布)”,我认为的答案是他们最终让alloc稳定下来。目前,no-std target 无法访问堆,除非它们跳上“Nightly”列车,在这种情况下,你又回到了 Python 式的噩梦,你的代码经常因语言版本而中断。

    我们绝对给了用no-std和 Stable Rust编写操作系统一个公正的机会。Xous第一年的开发都是用no-std完成的,在内存空间和复杂性方面付出了代价。我们有可能只用预先分配好的静态数据结构来编写操作系统,但我们必须在所有情况下满足最坏情况下的元素数量,这导致了臃肿。此外,我们还不得不推出很多自己的核心数据结构。

    大约一年前,当Xobs将Rust的std库移植到Xous时,这一切都改变了。这意味着我们能够在稳定的Rust中访问堆,但这是有代价的:现在Xous被捆绑在一个特定的Rust版本上,因为每个版本的Rust都有自己独特的std打包版本。这个版本的绑定是有原因的:std是可以将内存分配和线程创建等基本 Unsafe 的硬件结构变成 Safe 的Rust结构的地方。(我最近还了解到一个有趣的事实。Rust对于大多数 target 没有本地分配器--它只是简单地使用libc的malloc()和free()函数!) 换句话说,Rust能够有力地保证稳定版本的“火车”不破坏旧的功能,部分原因是所有的松散部分都被扫进了std。

    我必须不断提醒自己,拥有 std 并不能消除关键代码中严重安全漏洞的风险——它只是将许多关键代码移到了标准库中。是的,它是由一群比我聪明的天才程序员维护的,但归根结底,我们都只是人类,我们都是软件供应链攻击的公平目标。

    Rust有一个发条式的发布时间表:每六周就会推送一个新版本。由于我们的 "std "分叉与特定的Rust版本相联系,这意味着每六周,Xobs都要承担更新我们的分叉并为其建立新的 "std "版本的艰巨任务(我们不是Rust的一级平台,这意味着我们必须维护自己的 "std "库)。这意味着我们同样迫使所有Xous开发者在他们的工具链上运行rustup update,这样我们才能保持与语言的兼容性。

    这可能是不可持续的。最终,我们需要锁定代码库,但我没有一个明确的退出策略。也许我们可以考虑回到 "nostd "的下一个时间点,就是我们可以获得稳定的 "alloc "功能,这让我们可以再次访问堆。这样我们就可以把Xous从Rust发布的列车上解开,但我们仍然需要回填一些功能,如 Vec、HashMap、Thread和 Arc/Mutex/Rc/RefCell/Box结构,使 Xous 能够有效地进行编码。

    不幸的是,alloc' crate 非常难,而且已经开发了很多年了。虽然如此,我真的很欣赏Rust在开发这一功能背后的透明度,以及为稳定这一功能所做的努力和思考。

    译者注:这一点,也许学习一下 Android 和 Fuchsia 如何引入 Stable Rust 工具链会对他有所启发。当然,因为 Xous 是纯 Rust 实现,而 Android 和 Fuchsia 是部分模块或组件用 Rust,后者可能没有 Xous 的麻烦。

    Rust 对供应链安全的观点有局限

    我认为这一立场被rustup.rs安装页面推荐的安装方法很好地概括了: “嗨,在你机器上运行这个来自随机服务器的 shell 脚本。”

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    

    公平地说,你可以下载脚本并在运行前检查它,这比 Windows .MSI安装程序的vscode要好得多。然而,这种做法充斥着整个构建生态系统:每当你从crates.io Pull 一个新的crate时,一个名为build.rs的桩代码就有可能被编译和执行。这一点,加上 "宽松 "的版本定位(你可以指定一个版本,例如,简单的 "2",这意味着你将抓取任何最新发布的版本,主要版本为2),使我对通过crates.io生态系统发起软件供应链攻击的可能性感到不安。

    Crates.io还受到一种错别字的影响,很难确定哪些是 "好 "的,哪些是 "坏 "的;一些名字和你想要的一模一样的 crate,结果只是旧的或被放弃的早期尝试,给你提供了你想要的功能,而更受欢迎的、积极维护的 crate 不得不采取不太直观的名字,有时与其他 crate 只有一两个字符的差别(公平地说,这不是Rust的包管理系统特有的问题)。

    还有一个事实是,依赖关系是链式的--当你从crates.io Pull 一个东西的时候,你也 Pull 了该crate的所有附属依赖关系,以及所有最终会在你的机器上运行的build.rs脚本。因此,仅仅审核Cargo.toml文件中明确指定的crate是不够的,你还必须审核所有依赖的crate,以防止潜在的供应链攻击(upply chain attacks)。

    幸运的是,Rust允许你使用 Cargo.lock 文件将 crate 固定在一个特定的版本上,你可以完全指定一个依赖 crate ,直到次要版本。在Xous中,我们试图通过发布Cargo.lock文件和指定所有第一阶的依赖 crate 到次要版本的政策来缓解这一问题。我们还对某些 crate 做了本地备份(vendored)和 forked,否则会使我们的依赖树增长而没有什么好处。

    这就是说,我们的大部分调试和测试框架都依赖于一些相当花哨和复杂的 crate,这些crate Pull 了大量的依赖关系,而令我懊恼的是,即使我试图为我们的目标硬件运行一个构建,用于在主机上运行模拟的依赖 crate 仍然被 Pull 了下来,build.rs脚本即使没有运行,至少也被构建了。

    针对这种情况,我写了一个叫 crate-scraper[13]的小工具,它可以下载Cargo.toml文件中指定的每一个源码包,并将它们存储在本地,这样我们就可以有一个用于构建Xous版本的代码快照。它还可以进行快速的 "分析",即搜索名为build.rs的文件,并将它们整理成一个文件,这样我就可以更快速地通过grep来寻找明显的问题。当然,人工审查并不是检测嵌入build.rs文件中的巧妙伪装的恶意软件的实用方法,但它至少让我了解我们正在处理的攻击面的规模: 它是令人惊叹的[14],大约有5700行来自不同第三方的代码,它们操纵文件、目录和环境变量,并且在我每次进行构建时在我的机器上运行其他程序。

    我不确定这个问题是否有好的解决方案,但是,如果你是超级偏执狂,而且你的目标是能够构建可信赖的固件,那么就要警惕Rust的广泛的软件供应链攻击面。

    你无法重现(reproduce)别人的 Rust 构建

    我对Rust的最后一个问题是,在不同的计算机之间,构建是不可重现的(如果我们禁用我在Xous中为$reasons而嵌入的时间戳,它们至少在同一台机器上的构建之间是可重现的)。

    我认为这主要是因为Rust将源代码的完整路径作为二进制文件中的恐慌(panic)和调试(debug)字符串的一部分拉进来。这导致了一些不舒服的情况,我们在 Windows 上构建了工作,但在 Linux 下失败了,因为我们的路径名在两者上的长度非常不同,这会导致一些内存对象在目标内存中移动。公平地说,这些失败都是由于我们在 Xous 中存在的错误,这些错误已经得到修复。但是,知道我们最终会有用户向我们报告我们无法重现的错误,这感觉并不好,因为他们在构建系统上的路径与我们的不同。对于想要通过构建自己的版本并将哈希值与我们的哈希值进行比较来审核我们发布的用户来说,这也是一个问题。

    在Rust的维护者那里有一些bug,以解决可重复构建的问题,但由于他们必须处理语言中的许多问题,我对这个问题能否很快得到解决并不感到乐观。假设导致不可重现性的唯一原因是二进制文件中包含了操作系统的路径,那么解决这个问题的一个办法就是重新配置我们的构建系统,使其在某种chroot环境或虚拟机中运行,以一种几乎任何人都能重现的方式修复路径。我说 "几乎任何人 "是因为这个修复方法将取决于操作系统,所以我们将能够在例如Linux下获得可重复的构建,但它不能帮助Windows用户,因为chroot环境不是一个东西。

    Rust 超乎预期的地方

    尽管这里列出了所有的抱怨,但我认为如果我必须重新做一遍,Rust 仍然是我用于 Xous 的有力竞争语言。我做过 C、Python 和 Java 的大型项目,所有这些项目最终都背负着“不断增加的技术债务”(可能有一个软件工程师的术语来描述这种情况,我只是不知道)。问题往往是从一些数据结构开始的,我在第一遍的时候不能完全弄好,因为我还不知道这个系统是如何组成的;所以为了弄清楚这个系统是如何组成的,我就用一个半生不熟的数据结构拼凑出一些代码。

    于是就开始陷入混乱:一旦我对事情的运作有了一个概念,我就回去修改数据结构,但现在在其他地方出现了一些未曾预料到的、微妙的破坏。也许这是一个逐个击破的问题,或者一个符号的极性似乎被颠倒了。也许这是个轻微的竞态条件,很难说清楚。没关系,我可以通过把<=改成<,或者修改符号,或者增加一个锁来解决这个问题。我仍然在充实这个系统,对整个结构有一个概念。最终,这些小的 hack 代码(意指非正规写法,只图完成功能)往往会转移到每一个依赖的模块中,因为事情的全部原因是由于 "作弊 "而产生的;当我回去切除这些 hack 代码时,我最终得出结论,它不值得努力,所以下一个最好的选择是把整个事情烧掉重写...但不幸的是,我们已经落后于计划和预算,所以重写从未发生,而hack代码继续生存。

    Rust是一种很难编写代码的语言,因为它使这些 "作弊 "变得很难:只要你有纪律,不使用 Unsafe 的结构来使作弊变得容易。然而,真正的困难并不意味着不可能--在构建Xous的过程中,肯定有一些作弊行为被掩盖了起来。

    这就是 Rust 真正超出我预期的地方。该语言的结构和工具非常擅长追捕这些作弊并对重构代码库有帮助,从而能达到“治愈癌症而不杀死患者”的效果,可以这么说。这就是 Rust 非常严格的类型和借用检查器将生产力负债转换为生产力资产的点。

    我把它比作在穿过建筑物的复杂电缆束中更换电缆。在 Rust 中,可以保证电缆槽中的每一根线,无论线束变得多么复杂和糟糕,都是可分离的,并且两端都有清晰的标签。因此,您始终可以“拉到一端”并通过更改结构中元素的类型或方法的返回类型来查看另一端在哪里。在较不严格类型的语言中,您不会获得此属性;电缆可以在电缆槽内的某处合并并相互影响,因此在进行更改后,您只能通过手动测试“嗡嗡作响”每条电缆。即使这样,您也永远无法确定当有人打开浴室灯时,您更换的东西是否会导致咖啡机关闭。

    这里有一个能说明Rust的重构能力在Xous中的作用的示例。在我们的图形子系统(我称之为GAM(Graphical Abstraction Manager[15]))中,处理信任级别的方式有一个问题。系统中的每个Canvas都有一个u8'分配给它,这是一个信任等级。当我开始写GAM时,我只知道我想要一些关于Canvas的可信任度的概念,所以我添加了这个变量,但并不确定它到底会被如何使用。几个月后,系统增加了带布局的上下文概念,布局是定义特定类型互动的多画布结构。现在,你可以有多个信任等级与一个上下文相关联,但我已经忘记了我之前放在Canvas结构中的信任变量--并且在上下文结构中也添加了另一个信任等级数字。你可以看到这是怎么回事:只要我有简单的测试案例,一切都能正常工作,但当我们开始在应用程序上弹出窗口,然后在窗口之上的菜单等等,疯狂的行为开始显现,因为我已经混淆了信任值的存储位置。有时我在更新Context中的值,有时我在更新Canvas中的值。它有时会表现为一个逐个击破的错误,有时则表现为一个并发错误。

    这一直是困扰我的一件难以描述的事,而GAM已经成长为一个有许多移动部件的5千行的畸形代码。最后,我决定必须对此做些什么,但我真的不希望这样做。我认为我搞砸了什么,这次调查将以重写整个模块而告终。

    幸运的是,Rust给我留下了一根小小的绳子。Clippy,也就是Rust中的 "linter",在我认为应该使用信任度变量的地方发出了一个警告--我在Context中存储了它,但之后没有人提到它。这很奇怪--它应该在每次重绘上下文时都是必要的!因此,我开始删除变量。所以,我开始删除这个变量,看看有什么问题。这很快让我想起,当画布被创建时,我也在画布内存储了信任度,这就是为什么我有这个悬空的引用。一旦我有了这个线索,我就能够重构信任的计算,只参考那个基础真理的来源。这也让我发现了其他一直潜伏着的错误,因为事实上我从来没有行使过一些我认为是常规使用的代码路径。经过几个小时的探究,我对这一切是如何运作的有了清晰的认识,我用简单易懂的API重构了信任计算系统,而不必折腾整个代码库。

    这只是我在维护Xous代码库时使用Rust的许多积极经验之一。这是我第一次抬头挺胸,以积极的态度走进一个大版本,因为这是第一次,我觉得也许我有机会能够以诚实的方式处理困难的bug。我花在脑子里找借口的时间越来越少,以证明为什么事情是这样做的,为什么我们不能接受那个 Pull Request,而花更多的时间思考所有的事情可以变得更好,因为我知道Clippy在支持我。

    对看此篇文章的 Rust 开发者的告诫

    无论如何,对于一个硬件人(指作者本人)来说,这是很多关于软件的吐槽。很快就会有软件开发者提醒我,首先,我做的是电路和铝壳,而不是写代码的,所以我没有资格抱怨软件。他们是对的。我实际上没有接受过“以正确的方式”编写代码的“正式”培训。当我在大学时,我学习了麦克斯韦方程,而不是算法。我永远不可能成为一名专业的程序员,因为我连最简单的编码面试都过不了。不要让我写链表:我已经知道我不知道如何正确地去做;你不需要向我证明这一点。这是因为每当我发现自己在写一个链表(或任何其他基础数据结构)时,我都会立即停下来,质疑所有让我走到那一步的人生选择:这不是库的用途吗?难道我真的需要重新发明轮子吗?如果在编码面试中表现出色与实际编码能力之间存在任何关联,那么您绝对应该对我的意见持保留态度。

    尽管如此,在花了几年时间使用Rust并阅读了无数关于该语言的文章之后,我觉得也许发表一篇关于该语言的批判性观点的文章会让人耳目一新。

    参考资料

    [1] Rust: A Critical Retrospective:https://www.bunniestudios.com/blog/?p=6375: https://www.bunniestudios.com/blog/?p=6375

    [2] Xous: https://betrusted.io/xous-book/

    [3] QNX: https://en.wikipedia.org/wiki/QNX

    [4] Xous: https://github.com/betrusted-io/betrusted-wiki/wiki

    [5] Precursor: https://precursor.dev/

    [6] 称为PDDB: https://www.bunniestudios.com/blog/?p=6307

    [7] CPU运行在FPGA中: https://github.com/betrusted-io/betrusted-soc

    [8] CHERI: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/

    [9] 正在改变: https://gankra.github.io/blah/fix-rust-pointers/

    [10] 第12章: https://docs.python.org/3/tutorial/venv.html

    [11] eli5 风格: https://doc.rust-lang.org/rust-by-example/attribute/cfg.html

    [12] 正式的语法定义: https://doc.rust-lang.org/reference/conditional-compilation.html

    [13] crate-scraper: https://github.com/betrusted-io/crate-scraper

    [14] 令人惊叹的: https://github.com/betrusted-io/crate-scraper/blob/main/builds.rs

    [15] Graphical Abstraction Manager: https://github.com/betrusted-io/xous-core/tree/main/services/gam