隐写术 20 - 从文本生成旋律。






4.98/5 (25投票s)
通过对音符进行排序来编码文本。
引言
在 隐写术 19 - 代码的顺序 中,您学习了如何通过对任意集合进行排序来编码消息。音乐由旋律组成,旋律是音符的集合。为什么不创作一首歌曲来编码旋律中的文本呢?
您需要定义的只是要在歌曲中使用的音符集合。由于有 Factorial(count)
种可枚举的排列,更多的可能音符意味着更大的秘密消息字母表。在本文中,我们不会花费时间讨论和声和作曲。我们将混合整个半音阶来编码一个长词或几个短词。对于较长的消息,您可以连接几个旋律。
Hello World
让我们从一个简单的例子开始。每个音阶有 12 个音符,两个音阶有 24 个音符,这足以满足“hello world”。消息文本被视为 BigInteger
。空消息是 '0',这是音符的默认排序。
我决定允许 42 个不同的字符:a-z 0-9 .:() 和空格。使用这个字母表,“hello world”的数字表示如下计算:
h = 7 w = 22
e = 4 o = 14
l = 11 r = 17
l = 11 l = 11
o = 14 d = 3
------------------------
7 * (42^10) h
+ 4 * (42^9) e
+ 11 * (42^8) l
+ 11 * (42^7) l
+ 14 * (42^6) o
+ 36 * (42^5) [space]
+ 22 * (42^4) w
+ 14 * (42^3) o
+ 17 * (42^2) r
+ 11 * (42^1) l
+ 3 * (42^0) d
------------------------
= 121297199112622725
这个数字可以被馈送到 前面解释过的 算法中,以半音阶作为载体列表。(非音乐家的提醒:C C# D D# E F F# G G# A H B c c# d d# e f f# g g# a h b。)
结果如下:
d d# D e f A G# f# F H g F# C# E g# c# B a G D# c C h b
字母更少,单词更多
最大数字消息(因此文本消息的长度)受 Factorial(countNotes)
的限制。要编码更多文本,我们可以使用更多音符,或者保持数字值更小。在上面的例子中,基数 42 产生了非常高的值。如果您将字符限制为 a-z 和空格,则基数为 27,“hello world”的值仅为 1474967912327400。这意味着,我们可以将更长的文本存储在相同长度的旋律中。
7 * (27^10) h + 22 * (27^4) w
+ 4 * (27^9) e + 14 * (27^3) o
+ 11 * (27^8) l + 17 * (27^2) r
+ 11 * (27^7) l + 11 * (27^1) l
+ 14 * (27^6) o + 3 * (27^0) d
+ 36 * (27^5) [space]
---------------------------------------------------
= 1474967912327400
节奏 - 纯属娱乐
一连串普通的四分音符听起来可能很无聊。但一旦音符排序完毕,您就可以在任何地方插入重复项。所有重复项将在解码前被删除。由于时间并不重要(至少在这个原型中),您可以随意将四分音符拆分为八分音符。这些都不会影响编码的消息。以下是“coding in c sharp”的几个版本(对于 27 个字符的字母表,该数字为 201255931456816565832252)。
- 文本:“coding in c sharp”
- 音阶:从 A 开始
- 旋律:f e c# b g a G h F# H g# G# A D c f# E F C d C# B d# D#
- 文本:“coding in c sharp”
- 音阶:从 D 开始
- 旋律:H A F# e c d C d# b D# c# C# D g F B a h f G f# E G# g#
- 文本:“coding in c sharp”
- 音阶:从 F 开始
- 旋律:c# c A g d# f D# f# D F# e E F h G# d C C# g# H a G B b
- 文本:“coding in c sharp”
- 音阶:从 G 开始
- 旋律:dis d B a f g F gis E Gis fis Fis G C H e D Dis h c b A cis Cis
演示应用程序
该演示应用程序让您通过四个步骤将文本编码为音乐:
- 选择半音阶的偏移量(为将来的使用命名为调性)。
- 选择一个字母表。所选字符显示在标题栏中。
- 输入您的消息。
- 混合您的旋律。如果结果不够理想,请勾选“随机旋律”并一次又一次地混合,直到听起来可以接受为止。
当然,您也可以将旋律解码回文本。
- 选择用于编码的偏移量。
- 选择相同的字母表。
- 在结果框中输入音符名称。
- 将音符取消混合为纯文本。
该应用程序是为演示而编写的,因此存在一些隐藏功能,不会通过可见按钮或菜单干扰听众。
数字游戏
有些极客问我 pi
的文本含义是什么。在这些情况下,文本和数字字段可以互换:双击“内容数字”字段。然后它将变得可编辑,您输入的数字将被解码为文本。
快速笔记
要保存 TextBox
的内容以备将来使用,请聚焦该框并按 Ctrl+Y。文本将被附加到可执行文件目录中的 clipboard.txt。
保存图片
该应用程序同步显示结果作为音符名称和绘制的音符。但由于只有音符名称可以输入并重新解码,因此只能将它们复制到剪贴板。不过,有一种方法可以抓取图片:左键单击 PictureBox。音符将被保存到可执行文件目录中的 PNG 文件。
保存声音
“播放”按钮发出的旋律也可以保存:右键单击 PictureBox。声音将被保存到可执行文件目录中的 WAV 文件。
Mono/Linux 的解决方法
在某些 Mono 版本和音频驱动程序的组合下,Console.Beep
会保持静默。如果您遇到此类问题,请在 Form1.cs 中定义预编译器变量 IsMono
。
#define IsMono
代替蜂鸣声,应用程序将把声音保存到临时文件,并让 SoX 播放它。与通常的行为相比,不应有任何可见/可听见的区别。
Outlook(展望)
演示应用程序仅展示了基本思想。也许我会对其进行增强,以将长消息分割成几个旋律部分,确保特定的调性,为给定的旋律添加和声而不是生成随机旋律,等等。作曲家在他们的歌曲中添加秘密内容是没有限制的。