2017-08-27 3 views
0

私たちがコードで生成する「ランダムな」数字は、実際には擬似ランダムであることがわかります。 Javaの場合、デフォルトでタイムスタンプをランダムシードとして使用し、それ以降に生成されるすべての乱数はその時点から確定的に作成されます。オーディオ信号を使用したランダムキーの作成

乱数を使用してパスワードを生成し、悪意のある人物がそのパスワードを生成した日を知っている場合、その日のミリ秒ごとに反復するだけで済みます。それは1000 * 60 * 60 * 24 = 8,640万になります。これは洗練されたパーティーのための非常に多くの推測ではありません。エドワード・スノーデンは、「あなたの敵は1秒あたり1兆の推測が可能であると想定する」と有名に警告しました。

問題は、本当に乱数をどのように生成するかです。私が望むのは、自分のラップトップのマイクから16ビットのオーディオをサンプリングし、シードを形成するために2つのサンプルの最下位8ビットを使用することです。ここでのアイデアは、オーディオ信号の最も重要でない部分がノイズが運ばれる場所であるということです。波が記録されている意味

0,19 
0,38 
0,-49 
1,93 
1,-29 
1,-80 

あなたは最上位バイトが0または1であることを確認することができ、たとえば、ここでは比較的かなりの場所に記録されている16ビットのサンプルから数2バイトの値は、かろうじて登録していた。一方、最下位バイトの値はすべての場所でジャンプしています。それはランダムな種子の肥沃な土地です!

このポストの特定の質問は、私たちの周りの現実世界のノイズによって生成されるノイズ信号を使用して、ランダムな32文字のパスワードを生成する方法です。

+0

自己回答の質問は、特定の_question_の形ではなく、オープンエンドのプロジェクトを取る必要があります。 – duskwuff

+0

または、Math.random()+ Math.random()+ Math.random() 'を使用するか、または" secure " –

答えて

-1

これは素晴らしい午後のプロジェクトでした。ここでは、ランダムなintまたは任意の長さのランダムな文字列を生成できる静的メソッドを持つユーティリティクラスを示します。

生産(私にとっては)何回か実行

Gist link.

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 
関連する問題