眠いので、数年前に作ってお蔵入りしていたソースをとりあえず貼ってみた。
最近はこんな風にランダムな値を作ることはしないのかしらね。
自分でもかなり忘れている。
import java.security.SecureRandom; import java.util.Random; /** * ランダムな文字列を作成する。 * ランダムに生成したx個のバイト列を基にbase64の方法でバイトから下の値で変換していく。 * * ランダムに生成したbyte配列から3byteずつ取り出す。 * base64形式でbyteをascii文字に変換していくため。 * 3byte=24bitだからそれを演算で結合していく。 * 00000000 11111111 00010111こんな感じのを * 000000 001111 111100 010111このように6bitずつ使いたい。 * そのため、byte配列をビット演算する。 * 1byte目を左に16bitシフト、2byte目を左に8bitシフト、3byte目をor演算。 * これをint型に入れる。残りの8bitは0が入る。 * 00000000 00000000 11111111 00010111こんな感じ。 * 今度はこれから6bitずつ値を取り出す。 * 右に18bit, 12bit, 6bit, 0bitシフトし、111111(10進数なら63)でand演算をそれぞれ実行。 * * 00000000 00000000 11111111 00010111 * 111111 * 00000000 00000000 11111111 00010111 * 11 1111 * 00000000 00000000 11111111 00010111 * 1111 11 * 00000000 00000000 11111111 00010111 * 111111 * * 32bitで見てみると先ほどの24bitを4等分にしたint型の値を取得できる。 * * 実際のand演算は以下。 * * 00000000 00000000 00000000 00000000 * 00000000 00000000 00000000 00111111 * * 00000000 00000000 00000000 00001111 * 00000000 00000000 00000000 00111111 * * 00000000 00000000 00000011 11111100 * 00000000 00000000 00000000 00111111 * * 00000000 00000000 11111111 00010111 * 00000000 00000000 00000000 00111111 * * 得られた4つのint値でA〜/までの値を含む文字列から該当順序にある文字を取り出す。 * * これを3byteずつ取り出して繰り返す。 * * 端数となる場合(残り2byte, 1byteの時)、bitが6の倍数となるようパディングを行う。 * 残り2byteの場合、2bit足りないので左に2bitシフト演算し、0パディングする。 * 残り1byteの場合、4bit足りないので左に4bitシフト演算し、0パディングする。 * その後は上記と同様に処理をして文字を取り出す。 * base64では文字は4つずつなので足りない場合「=」を付け足して増やす。 * * * ランダムな英数字のみが必要な場合はその後、+/や=の値を変換する処理を入れる。 * ちなみに今の処理では、指定する値はbyte数であるため、実際に作成される文字数はそれより多くなる。 * * @author お屠蘇 * */ public class Samplepleple { private static final String des = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; private static final char equal = '='; private static final Random num_randam = new Random(); //とりあえず、デフォ使用。 private static final SecureRandom random = new SecureRandom(); /** * @param args */ public static void main(String[] args) { int len = 10; for(int i=0;i<len;i++) { int xd = 24; getSecureRandumString(xd); } } public static String getSecureRandumString(int len) { if(len <= 0) { return null; } byte[] bytes = new byte[len]; random.nextBytes(bytes); byte[] bytecp = bytes.clone(); StringBuilder buf = new StringBuilder(); int encount = 0; int total = bytes.length; int lastcount = 0; if (total - 3 < 0) { //どうしようかね。 } for (; encount < bytes.length; encount=encount+2) { if (total - 3 < 0) { lastcount = total; break; } total = total - 3;//3byte取り出す=24bit //int 32bit byte n1 = bytes[encount]; byte n2 = bytes[encount+1]; byte n3 = bytes[encount+2]; //24bit //000000 001111 111100 010111 int n123 = n1 << 16 | n2 << 8 | n3 ; //010100 001111 111100 010111 //111111 111111 111111 111111 //6bitであることに注意。0xfは4bit int b1 = (n123 >>> 18) & 63; int b2 = (n123 >>> 12) & 63; int b3 = (n123 >>> 6) & 63; int b4 = n123 & 63; buf.append(des.charAt(b1)) .append(des.charAt(b2)) .append(des.charAt(b3)) .append(des.charAt(b4)); } //残り2byte 16bit/6=2 rm4bit if (total == 2) { byte n1 = bytes[encount]; byte n2 = bytes[encount+1]; int n123 = (n1 << 8 | n2) << 2; //18bit //11111111 11111111 0000 //111111 111111 111100 int b1 = (n123 >>> 12) & 63; int b2 = (n123 >>> 6) & 63; int b3 = n123 & 63; buf.append(des.charAt(b1)) .append(des.charAt(b2)) .append(des.charAt(b3)) .append(equal); encount++; encount++; } else if (total == 1) { //残り1byte 8bit/6=1 rm2bit byte n1 = bytes[encount]; int n123 = n1 << 4; int b1 = (n123 >>> 6) & 63; int b2 = n123 & 63; buf.append(des.charAt(b1)) .append(des.charAt(b2)) .append(equal) .append(equal); } String reVal = buf.toString(); char[] chval = reVal.toCharArray(); for (int i = 0; i < chval.length; i++) { char x= chval[i]; if (des.charAt(63) == x || des.charAt(62) == x || equal == x) { int xd = num_randam.nextInt(61); chval[i] = des.charAt(xd); } } String newval = new String(chval); int randumlen = len; if (newval.length() - len >= 0) { randumlen = len; } else { randumlen = 0; } String val = newval.substring(0, randumlen); System.out.println("引数: " + len); System.out.println("整形: " + reVal); System.out.println("最後: " + newval); System.out.println("カウント: " + newval.length()); System.out.println("求められる文字数: " + len); System.out.println("出力する文字数: " + val.length()); System.out.println("結果: " + val); System.out.println(); return val; } }
実行したらこんな感じになりました。
動いたから良かった。(^O^)
引数: 24 整形: zgUc///X///L///s///Z///3/6Bw//+a 最後: zgUcq3GXmPNLNlkskArZI4t3E6BwZYIa カウント: 32 求められる文字数: 24 出力する文字数: 24 結果: zgUcq3GXmPNLNlkskArZI4t3