Skip to content

Instantly share code, notes, and snippets.

@brianrisk
Created August 27, 2017 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianrisk/c38ebc71c625533205f19b3023f8285b to your computer and use it in GitHub Desktop.
Save brianrisk/c38ebc71c625533205f19b3023f8285b to your computer and use it in GitHub Desktop.
Java - Creating a random key using audio signal
package com.geneffects.utilities;
import javax.sound.sampled.*;
/**
*
* Utility class for random number and random key creation.
*
* NOTE: requires a microphone/soundcard. (Probably won't work on your server!)
*
* Turns on the microphone and collects the least-significant 8 bits out of 16-bit samples to
* generate random numbers.
*
* Created by brianrisk on 8/27/17.
*/
public class RandomFromAudio {
public static final String ALLOWED_CHARACTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment