创建使用音频信号
问题描述:
我们知道,我们在我们的代码生成“随机”的数字真的是伪随机的随机密钥。在Java的情况下,它们默认使用时间戳作为随机种子,并且在此之后生成的每个随机数都是从该点向前确定性创建的。创建使用音频信号
如果使用随机数生成密码和恶意方知道你生成的内容一天,密码,他们就只有通过这一天每毫秒进行迭代。那将是1000 * 60 * 60 * 24 = 86.4百万。对于一个复杂的派对来说,这不是一个大数目的猜测。着名的爱德华斯诺登警告说,“假设你的对手每秒能猜出一万亿次。”
的问题是,我们如何产生真正的随机数?我想从我的笔记本电脑的麦克风中采样16位音频,并使用两个采样中最不重要的8位来形成种子。这里的想法是音频信号的最不重要的部分是噪声被携带的地方。例如,这里有从记录在一个相对安静的地方一个16位采样几两字节值:
0,19
0,38
0,-49
1,93
1,-29
1,-80
你可以看到,最显著字节为0或1,这意味着正在记录的波几乎没有注册。另一方面,最不重要的字节值在整个地方跳跃。这是随机种子的肥沃土壤!
这个职位存在的具体问题:我们如何能生产使用producedby我们身边的真实世界的噪音带来的干扰信号中的随机32个字符的密码。
答
这是一个阳光明媚的下午的项目!这是一个带有静态方法的工具类,可以产生一个随机整数或任意长度的随机字符串。
import javax.sound.sampled.*;
public class RandomFromAudio {
public static final String ALLOWED_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Demonstrating the methods
public static void main(String[] args) {
System.out.println(getRandomKey(32));
}
public static String getRandomKey(int keyLength) {
int [] randomInts = getRandomIntArray(keyLength);
StringBuilder stringBuilder = new StringBuilder();
for (int randomInt: randomInts) {
char randomChar = ALLOWED_CHARACTERS.charAt(randomInt % ALLOWED_CHARACTERS.length());
stringBuilder.append(randomChar);
}
return stringBuilder.toString();
}
public static int [] getRandomIntArray(int desiredLength) {
int [] out = null;
AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true);
TargetDataLine microphone;
try {
out = new int[desiredLength];
byte[] data = new byte[2];
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
microphone = (TargetDataLine) AudioSystem.getLine(info);
microphone.open(format);
microphone.start();
// my microphone seems to need to "warm up".
// It gets a lot of low signal at the beginning producing a lot of low numbers.
// This loop reads signal until it shows that a decently high value can be reached.
while (data[1] < 100) {
microphone.read(data, 0, data.length);
}
byte [] leastSig = new byte[2];
for (int i = 0; i < desiredLength * 2; i++) {
microphone.read(data, 0, data.length);
// saving the least significant byte
leastSig[i % 2] = data[1];
if (i % 2 == 1) {
// combining the bytes into an int
out[(i + 1)/2 - 1] = leastSig[0]<<8 &0xFF00 | leastSig[1]&0xFF;
}
}
microphone.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
return out;
}
}
运行产生了一些次(对我来说):
hqctXiTiV67iI2JAXrcU0vzGhxEBDN2R
ViCSGxahmI51mXfBIV7INo9vu3ZuKNDi
9oTl1Meer59Y69yxNRTa0Dv3pWNywZFY
zfLrh9ZU8oNLg43M1D1ZzcoSxJ4X1HOQ
dlhliKxM4tAhr8uoCOtdRsmwARIE6Gjb
自我回答问题,应该采取特定_question_的形式,而不是开放式的项目。 – duskwuff
或者干脆使用'的Math.random()'或者,如果你想 “保护”' “” +的Math.random()+的Math.random()+的Math.random()':d –