android实现真随机数生成器(物理随机)
原理:通过设备内置传感器生成随机散列字串,再通过取余等操作获取最终数字,这种方法不同于传统的伪随机数生成器,而是依赖于硬件,需要硬件支持。
private SensorManager sm;private int eventCount;private int flagCount;private StringBuffer mKeyBuffer = new StringBuffer();private boolean isRunning;private List<Integer> numbers = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_sensor);sm = (SensorManager) getApplicationContext().getSystemService(Service.SENSOR_SERVICE);List<Sensor> sensors = sm.getSensorList(Sensor.TYPE_ALL);for (Sensor sensor : sensors) {sm.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);}isRunning = true;//final StringBuffer values = new StringBuffer();new Thread() {@Overridepublic void run() {super.run();Dbg.print("====start====");while (isRunning) {try {Thread.sleep(500); //每隔500ms生成一个数} catch (InterruptedException e) {e.printStackTrace();}/*if (eventCount >= 100000) {break;}*/if (mKeyBuffer.length() == 0) {continue;}String source = mKeyBuffer.toString();mKeyBuffer.setLength(0);byte[] hash = getHash(source);if (hash == null) continue;BigInteger bi = new BigInteger(1, hash); //制作正整数int number = bi.testBit(0) ? 1 : 0; //生成0或者1,也可生成其它值//int randomInt = bi.remainder(BigInteger.valueOf(2147483648L)).intValue(); //生成随机int值if (number == 1) {flagCount++;}eventCount++;//numbers.add(number);Dbg.print(number, eventCount, flagCount, (float) flagCount / eventCount);}Dbg.print("====end====");}}.start();}@Overrideprotected void onDestroy() {super.onDestroy();sm.unregisterListener(this);isRunning = false;}private String makeEventKey(SensorEvent event) {StringBuilder sb = new StringBuilder();sb.append(event.timestamp);if (event.values != null) {for (float value : event.values) {sb.append("_").append(value);}}return sb.toString();}@Overridepublic void onSensorChanged(SensorEvent event) {String key = makeEventKey(event);mKeyBuffer.append(key).append("_");}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}public static byte[] getHash(String source) {MessageDigest digest = null;try {digest = MessageDigest.getInstance("SHA256");digest.update(source.getBytes());return digest.digest();} catch (Exception e) {e.printStackTrace();}return null;}