Intro

这篇文章会介绍几种我所知道的在音频里藏彩蛋的方法,例如Morse code、DTMF、SSTV、Backmasking和Spectrogram等,中间也会穿插一些奇奇怪怪但轻松有趣的知识。

本来打算把这篇文章的内容录制成播客,但想到这篇文章需要大量的图表展示,还是写成博客比较直观,这样也方便随时进行查阅,同时,我也有理由继续咕咕咕我的第0期播客了哈哈哈(其实已经想好一些要聊的话题了,敬请期待~)

这篇文章稍微有点长,你可以分几次看完,或者直接跳转到你感兴趣的部分阅读即可,每一小节都可以独立阅读,没有前后关联的知识,放轻松阅读,不要有压力~

这篇文章中的很多内容参考了好和弦NiceChord的视频把秘密訊息偷偷藏入音樂中!,感谢好和弦NiceChord频道创作的免费且质量超高的乐理课。

Methods

Morse code

在《编码:隐匿在计算机软硬件背后的语言》开头描述了这样一个场景:

你今年10岁,你最好的朋友就住在街对过。事实上,你们各自卧室的窗户正好彼此相对。每当夜幕降临,父母就如同往常一样,早早地催促你该上床睡觉了,但是你和你的朋友还想交流想法,交换见闻,分享各自的秘密,或者扯扯闲话,开开玩笑,聊聊梦想。

如果是你,你会如何跟就在窗户对面的好朋友扯扯闲话,开开玩笑,聊聊梦想呢?

  • 打开窗户聊天?不行,即使窗户相对,要让对方听得清还是得发出比较大的声音,声音太大有可能会被父母听到。

  • 把想说的话写在纸上,然后扔给对方?嗯,听起来好像可行的样子,但黑灯瞎火的既要写字又要阅读对方丢过来的小纸条好像又有点费劲。

这时候你发现了床头的手电筒。

对啊!可以通过手电筒的亮灭来传递信息,只要双方约定好了手电筒的亮灭状态分别代表什么信息不就行了吗!例如,亮一下代表A,亮两下(亮灭亮)代表B…以此类推,通过手电筒的亮灭就能表示26个英文字母了,也就能进行简单的信息交换了。

但…还是存在一些问题,如果想表达“Z”这个英文字母,那就需要亮26下手电筒,手电筒会不会容易坏不说,光开关26次手电筒就得花上不少的时间,所以就需要一份效率更高的对照表。

Morse code就是这样的对照表,Morse code由两种符号构成:dots (·)dashes (-),其中dots表示最小单位,dashes表示3倍长度的dots,Morse code的对照表如下图:

所以,就可以通过手电筒亮灭的时间长短来表示dots和dashes,例如亮1秒表示dot,亮3秒表示dash,这样一来,通过手电筒就能完成Morse code中所有字符的表示,进行信息的传递。

手电筒亮灭的时间长短是Morse code的一种表现形式,在声音里,自然就是声音的长短了。你一定在电视剧里看见过发电报的场景,听到过“嘀嘀嘀“、”嘀—嘀—嘀—”的电报声,其实那就是Morse code,顺便提一个小知识,这个“嘀嘀嘀“的声音其实是1000Hz的正弦波发出的声音,和用来消除f-word的“哔——”声是一样的。

你可以点击下方的按钮听听1000Hz正弦波发出的声音,也可以调整左侧的滑动条来听听不同频率正弦波所发出来的声音有什么不同:(播放之前注意降低一下耳机音量)

1000Hz

对照前面的Morse code码表,把Hello转换为Morse code就是.... / . / .-.. / .-.. / ---(这里我用/来分隔每一个字母),听起来像是这样子:

即刻2020年年度报告的末尾就通过Morse Code隐藏了一段文字,解码出来的信息是“Thanks for your addicted”,这句话其实也是即刻app里的一个彩蛋,当多次刷新“动态”页面的时候,app底部会显示“Thanks for your addicted”这一行小字。

这是即刻2020年度报告末尾摩斯电码彩蛋的音频,你可以听听看:

如果把这段音频放到音频编辑软件里,显示频谱图,对照Morse code码表就能翻译出对应的文字。例如,这是彩蛋“Thanks for your addicted”的第一个单词“Thanks”:

在小宇宙一周年祝福的末尾,也放了一段Morse code的彩蛋,想知道彩蛋具体是什么内容可以听听这期播客,自己试着解码一下哈哈(感谢@我不跑调):004 试试祝福

要生成Morse code的音频并不复杂,在Google上搜索morse code generator就能找到好多的Morse code生成器,例如这个:https://morsecode.world/international/translator.html,输入你想要的文字,然后直接下载生成好的音频就行了。

PS:前面提到的《编码:隐匿在计算机软硬件背后的语言》挺有意思的,书里介绍了很多计算机中所使用的编码知识,例如各种门电路、计算机是如何计算加法、减法的等,如果感兴趣可以去找来看看。如果你曾被数电、模电所困扰,看完这本书应该会觉得轻松很多。

Dual-tone multi-frequency signaling

Dual-tone multi-frequency,看这名字,又是dual又是multi的,一看就觉得很厉害的样子,但你的日常生活中肯定已经接触过这个东西了,甚至可能每天都会用到它,这个东西是平时打电话拨号时会用到的一项技术。

不知道你有没有想过,在使用座机拨打电话的时候,电信公司是如何知道我们所拨打的电话号码的,以及,为什么拨号键盘上的每个数字按下的声音听起来都有点不太一样。

和Morse code类似,Dual-tone multi-frequency其实是对拨号键盘每个按键的编码,简称为DTMF。如果把Dual-tone multi-frequency翻译成中文就是双音多频,从字面意思来理解,每个拨号按键都是由两个不同频率的声音来组成的。

DTMF的映射关系是这样的:

1209 Hz1336 Hz1477 Hz1633 Hz
697 Hz123A
770 Hz456B
852 Hz789C
941 Hz*0#D

下面有一些和DTMF不相关的文字,但是提到的内容挺有意思的,有空的话不妨看一看XD:


看到这个表格,你有没有发现电话键盘的布局和你电脑键盘上的数字键(或计算器键盘)布局不太一样。其实电话的拨号键盘最初设计了好多种不同的形式,最终是经过多次实验才确定下来的,Bell实验室的一篇文章详细讲述了现在常用的电话拨号键盘的布局是如何被设计、挑选出来的,如果想了解更多的可以去看看这篇文章:https://www.academia.edu/download/41999662/touchtone_hf.pdf

《星箭廣播》有一期节目则是介绍了iPhone键盘是如何设计的,也很有意思,如果有时间可以听听看:「現在開始你們都是鍵盤工程師!」iPhone 鍵盤的誕生與賈伯斯時代的蘋果軟體設計流程


好了,言归正传,例如在拨号键盘上按下123就能听到这样的声音:

把这段音频放到带有频谱分析功能的音频编辑软件中,可以看到每个按键都是上表中对应的两个频率声音的叠加:(例如①这个按键就是697Hz和1209Hz这两个声音的叠加)

因为拨号键盘的局限性,只有0~9的数字和几个字母和符号,要想使用DTMF来隐藏丰富的信息似乎有一些难度。

但如果把DTMF和手机上的输入法结合起来就很有意思了,想想在智能机还不是很普及的年代,手机还都是带有实体按键的,朋友之间发短信就只能通过手机上的十来个按键输入文字。(想当年,大家都练就了一副不看手机屏幕就能准确无误输入一大段文字的技能呢~)

当时的手机按键长这样:

每个按键分配了几个字母,通过这9个按键,就可以在手机上输入任何文字,例如,如果想在9键的输入法上通过拼音输入“你好”,就需要按下这几个键:64426

64426转换为DTMF音频作为彩蛋,探索彩蛋的人需要先识别出DTMF音频对应的数字,然后再通过手机输入法输入数字才能发现对应的文字,是一个很有趣的探索过程。

要制作DTMF音频(或者称之为拨号音)也很简单,依旧是在Google上搜索DTMF generator就能找到好多的Morse code生成器,例如这个:https://www.audiocheck.net/audiocheck_dtmf.php,输入你想要的拨号按键,然后直接下载对应的DTMF音频就行了。

Slow-scan television

既然通过声音可以传输字符,那么肯定还可以传输信息更加丰富的图片啦~只是编码的对象不同而已,Morse code和DTMF编码的对象是字符,而接下来要介绍的这个技术编码对象则是图片。

不知道你有没有好奇过,天上的卫星是如何向地面传输数据的,特别是如何将拍下来的照片传输到地面的。

Slow-scan television就是其中一种方法,简称为SSTV ,翻译为中文就是慢扫描电视,把图像信息编码到音频中进行传输。SSTV背后详细的编码细节这里就不展开了,如果感兴趣可以看看SSTV handbook来了解更多关于SSTV的编码细节。

一些卫星/空间站会定时向地面通过SSTV传输照片,例如国际空间站(International Space Station, ISS)会定期向地面通过SSTV传输一些照片:

曾经听到一期完全由SSTV构成的播客节目:

通过手机上的SSTV解码app解码这期播客的音频可以看到这样的图像:(看起来应该是播客封面的左上角)

如果你玩过Valve出品的游戏Portal,也许会对散布在游戏各处的收音机有点印象,它长这样:

这个形状看起来有点奇怪的收音机其实就埋藏着许许多多和SSTV有关的彩蛋,当游戏通关之后,再次进入游戏,将散布在关卡不同角落的收音机拿起来走到某个指定的位置就能接收到Morse code或SSTV的声音(这个过程就像是拿着收音机找信号哈哈),例如这是第一关SSTV彩蛋解码出来的图像:

更多关于Portal中SSTV彩蛋的细节可以在这个wiki上查看:https://half-life.fandom.com/wiki/Portal_ARG所以Portal什么时候出第3部呢!

想想在音频里藏入一段SSTV音频当彩蛋,听到音频的人想看到这张图片,就得拿着手机或电脑通过麦克风来接收藏在音频中的图片,随着音频的播放,图片逐渐拼凑完整,应该会是一个很有趣的过程~

生成SSTV同样可以在Google上搜索SSTV generator,就能找到很多将图片编码为SSTV音频的在线工具,例如这个:https://www.vr2woa.com/sstv/,或者也可以使用这个Python工具来将图片编码为SSTV音频:https://github.com/dnet/pySSTV

需要注意的是,SSTV有多种不同的模式,不同模式对应的音频长度和支持的图像分辨率也不一样,在生成SSTV音频的时候需要仔细确认所使用模式对应的图片分辨率。

Backmasking

看了这么多和编码相关的知识,是不是觉得自己已经看得头昏眼花了,那就下来就介绍一个很容易理解的方法,叫Backmasking。

Backmasking其实是一种录音技术,是指将声音或信息反向录制到要向前播放的轨道上。在数字音频还不是特别发达的年代,要录制Backmasking音频还需要通过磁带录音机来实现,但现在利用音频处理软件的reverse功能,就可以直接将一段音频反向播放,原本清晰的文字在经过倒放之后就会变得完全无法听出来在说什么。

下面这个视频是周杰伦2003年发布的歌曲《你听得到》的MV,注意听“秘密躺在我怀抱”的下一句:(已经设置好视频播放的时间节点,如果视频没有自动跳转到指定位置的话,麻烦你手动把进度条拉拽到2:43处。视频引用自YouTube,如果无法访问,下面也有一段截取出来的音频可以直接播放)

如果你无法播放上面的视频,这里有一段从《你听得到》歌曲中截取出来的音频:

“秘密躺在我怀抱”的下一句,虽然字幕显示的是“只有你能听得到”,但是是不是发现根本听不清在唱什么,其实这里就是一段Backmasking的音频。

如果把这段音频reverse回来就能听到歌词里显示的“只有你能听得到”,就像这样:

Wikipedia上有一个列表:List of backmasked messages - Wikipedia,列举了在音乐作品中出现的Backmasking,如果感兴趣可以把列表里相关的歌曲找来听一听,找找里面的Backmasking片段。

Backmasking的制作方法就不详细介绍了,大部分音频编辑软件(例如Adobe Audition等)应该都提供了reverse功能,选中你希望作为彩蛋的音频,将其reverse即可。

Spectrogram

所以…有没有什么方法是不容易听出来藏了信息的呢?那就是今天最后要介绍的一种藏彩蛋的方法了,把信息藏在声音的频谱图(Spectrogram)里。

频谱图看起来就像这样:

其中,横轴表示时间,纵轴表示频率,通过颜色来表示特定时间上某个特定频率的幅值。


更多关于频谱图的知识就不详细介绍了,其中涉及了傅里叶变换、小波变换等知识,比较复杂,如果你对其中的原理感兴趣可以看看3Blue1Brown的这期视频了解其背后的知识:https://www.youtube.com/watch?v=spUNpyF58BY我才不会告诉你其实我自己也不太懂傅里叶变换呢!

3Blue1Brown的视频质量都超高,如果对数学感兴趣真的强烈推荐去看看,会有种一看就不想停下来的冲动(我一般是一看就开始打瞌睡)。除了视频,3Blue1Brown最近也开始做播客了,RSS链接在这:https://anchor.fm/s/636b4820/podcast/rss


在著名沙盒游戏Minecraft中的一张唱片Disc 11里就藏了一个小彩蛋,用音频编辑软件打开Disc 11这张唱片,显示频谱图,定位到1:02左右:

(我在这张图的下半部分标注了彩蛋,原始频谱图可以看这张图的上半部分)

能在1:02之后看到跟Minecraft两大角色之一的Steve的脸很像的频谱图,在旁边还有几个数字:12418,把十进制的12转换为十六进制就是C,连起来就是C418,这正是这段音乐作者的名字。

有趣的是,这张名为Disc 11的唱片长度为1分钟11111微秒,不愧是Disc 11

接下来讲讲如何在音频的频谱图中隐藏文字信息,其实常用的音频编辑软件,例如Adobe Audition中,就提供了音频频谱的编辑功能,利用该功能就能很方便地制作Spectrogram彩蛋。

打开你想要的音频,点击下图红色方框所框住的按钮显示频谱图:

然后选择上图中黄色方框所框住的画笔🖊工具,在频谱图上通过画笔工具写上你想隐藏的文字:

画出想隐藏的信息后按下键盘上的Delete键即可:

不过,编辑频谱图会对原始音频产生一定的影响,有些时候编辑完听起来会觉得声音有点怪怪的。

还有一种方法是在白噪音的频谱图写上想隐藏的文字,然后把白噪音作为单独一轨,混入整体的工程中。

如果你听过传统的收音机,在搜台的时候就能听到类似的声音,白噪音听起来就像这样:(播放之前注意音量)

白噪音的频谱图非常均匀:

在白噪音的频谱图上写下想隐藏的文字之后,将其作为单独的一轨音频放到你的混音工程里,并将白噪音所在的轨道增益减小,小到正常音量播放时几乎听不到的程度,在最终混合生成的音频文件频谱图中就能看到被隐藏在白噪音中的信息。

你可以在这里下载到白噪音样本:https://www.audiocheck.net/testtones_whitenoise.php

Other

嗯…看了这么多,还有其他方法吗?

有,并且还有很多,如果感兴趣可以到Google Scholar搜索audio steganography,能找到很多相关的论文。

Easter egg?

一直觉得在作品中藏彩蛋是一件很浪漫的事。

找彩蛋的过程就好像陶渊明的《桃花源记》所描述的那样:

林尽水源,便得一山,山有小口,仿佛若有光,便舍船从口入。初极狭,才通人,复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田美池桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣著,悉如外人。黄发垂髫,并怡然自乐。

即刻app的“系统设置”页面和小宇宙app的“关于”页面里就藏了彩蛋,只要在这两个页面往上拉,就能发现隐藏的果果🐱和电池🔋:

即刻APP“系统设置”页面彩蛋小宇宙APP“关于”页面彩蛋

Google的很多产品里其实也藏了彩蛋,例如在Google搜索recursion,它会问你Did you mean: recursion:(这可能是一个只有程序员才懂的彩蛋哈哈哈)

最后,介绍一个记录彩蛋的网站:https://eeggs.com/,在这个网站里能找到许多藏在软件/电影/音乐/书里的奇奇怪怪的彩蛋,可惜这个网站似乎有一段时间没更新了。

恭喜你发现藏在这篇文章的彩蛋一枚~

References