我正在編寫一個Java程序,需要從系統的/ dev/urandom接口中提取32個字符的鍵。對於這一點,我使用下列程序:Bash在Java中不能正確執行
public String generateKey() {
try {
Runtime run = Runtime.getRuntime();
Process pr = run.exec("tr -cd '[:alnum:]' < /dev/urandom | fold -w30 | head -n1;echo;");
pr.waitFor();
BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = buf.readLine())!= null) {
sb.append(line);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
}
}
(如果不能做到這一點,然後它會返回一堆空字符)
出於某種原因,它返回什麼(或拋出異常並且不打印堆棧跟蹤)。我知道這一點,因爲我將它打印到控制檯(沒有),當我將它發送給我的RC4引擎時,它會拋出一個除零錯誤。爲什麼命令不起作用,我怎麼才能使它工作?
謝謝你的幫助。
編輯:我發佈這不是兩分鐘後,我推斷它沒有返回空字符,因爲我將它設置爲返回單詞「檸檬」,它做了同樣的事情,所以它沒有拋出異常。
編輯2:按在評論中我試圖從具有相同結果的文件向右讀,但我想我可能會做這種錯誤的建議......
File file = new File("/dev/urandom");
FileReader freader = null;
StringBuffer sb = new StringBuffer();
int x = 0;
try {
freader = new FileReader(file);
BufferedReader reader = new BufferedReader(freader);
for (int i=0;(i<32||(x=reader.read())==-1);i++) {
sb.append((char) x);
}
return sb.toString();
} catch(Exception e) {
e.printStackTrace();
return "a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
}
編輯3 :這可能有助於那些幫助: 使用上面的代碼和管道輸出到od我發現它只是讀0。 (同樣,它不是拋出一個異常,否則它不會是全零:)
# ./run.sh | od
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
只要*不*在最小的測試案例中捕獲異常[尤其是] ..不需要處理檸檬NULs。 – 2013-01-09 00:11:31
「不要發現異常」是什麼意思?如果我刪除了try/catch塊,編譯器會對我大吼。我認爲你的意思是不同的...... –
閱讀*檢查例外* - 這可能是這樣惱人的小動物 - 和'拋出'條款。如果這對其他方法(例如更大的上下文)是不可取的,只需簡單地將它包裝爲Unchecked:try {..} catch(Exception ex){throw new RuntimeException(ex); }'。這個和普通的日誌記錄之間的區別是這仍然會傳播一個異常 - 耶!只有在存在某種有用的情況下才能抑制異常(這可能是「壓制它」的情況,而不是在這裏/在測試用例中)。 – 2013-01-09 00:14:44