This article refer to http://www.vuln.cn/7117
Note: Static variable statics can be assigned multiple times, and it is not possible to assign a final static value multiple times
The linear congruence pseudo-random number algorithm LCG algorithm is mathematically based on the formula:
X (n+1) = (A * X (n) + C)% m
Among them, the coefficients are:
Die m, M > 0
Coefficient A, 0 < a < m
Delta C, 0 <= C < m
Original value (Seed) 0 <= X (0) < M
Where the parameters C, M, a is more sensitive, or directly affects the quality of pseudo-random number generation.
In general, a high LCG m is an exponential power of 2 (generally 2^32 or 2^64), as this allows the modulo operation to truncate the right 32 or 64 bits. Most compiler libraries Use this theory to implement its pseudo-random number generator rand ().
Here m take 2^32,a take 1664525,c take 1013904223
LCG Algorithm Implementation Example
public class lcg{public static int rand_state;public void My_srand (int init) {rand_state=init;} public static int rng_a=1664525;public static int rng_c=1013904223;public int My_rand () {rand_state=rand_state*rng_a; Rand_state=rand_state+rng_c;return rand_state & 0x7FFF;}}
Compile
Javac Lcg.java
Anti-compilation
Javap-c-verbose Lcg.class
Initialization of static blocks
static {};d Escriptor: () vflags:acc_staticcode:stack=1, locals=0, ARGS_SIZE=00:LDC #5//INT 1 6645252:putstatic #3//Field RNG_A:I5:LDC #6//int 10139042237:putsta Tic #4//Field RNG_c:I10:return
LDC #5 take constant 1664525 stack
Putstatic #3 The value from the top of the stack and into the static variable rng_a:i
LDC #6 take constant 1013904223 stack
Putstatic #4 The value from the top of the stack and into the static variable rng_c:i
Here Putstatic implements the initialization value of the static variable.
The following My_srand () function stores the input values in the Rand_state
public void My_srand (int);d escriptor: (I) vflags:acc_publiccode:stack=1, locals=2, Args_size=20:iload_11:putstatic # 2//Field Rand_state:I4:return
Iload_1//Press the first parameter (init) into the stack, why not iload_0? Iload_0 has been used in the default build constructor method.
(The ILOAD_0 is pressed into the top of the stack in the construction method)
Putstatic #2//Remove the value of the Init at the top of the stack and save the value to a static variable rand_state:i
Here to add, do not know whether it is the translator or the original author of the problem, the stored value should be the initialization of the class when the stack points of the static variable storage area, not the second storage bit said
See My_rand ()
Public int my_rand ();d escriptor: () iflags: acc_publiccode:stack=2, locals=1, args_size=10: getstatic #2 // field rand_state:i3: getstatic #3 // Field RNG_a:I6: imul7: putstatic #2 // Field rand_state:I10: getstatic #2 // Field rand_state:i13: getstatic #4 // Field RNG_c:I16: iadd17: putstatic #2 // Field rand_state:I20: getstatic #2 // FIELD&NBSP;RAND_STATE:I23:&NBSP;SIPUSH&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;3276726:&NBSP;IAND27: ireturn
The original text reviews 17 of putstatic #2和20的getstatic #2效率不高, which is actually just a translation of the Java statement
Try to
public int My_rand () {Rand_state=rand_state*rng_a;rand_state=rand_state+rng_c;return rand_state & 0x7fff;}
Change into
public int My_rand () {Rand_state=rand_state*rng_a+rng_c;return rand_state & 0x7fff;}
And look at this part of the anti-compilation
public int my_rand (); descriptor: () I flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: getstatic #2 // field rand_state:i 3: getstatic #3 // Field RNG_a:I 6: imul 7: getstatic #4 //&nbsP field rng_c:i 10: iadd 11: putstatic #2 // Field rand_state:I 14: getstatic #2 // field rand_ state:i 17: sipush 32767 20: iand 21: ireturn
In this way, the original 20 line removed, this should be in the source of the optimization of the JVM to optimize it, the JVM over-optimized and said the source is not good
Static variable access of Java Reverse Foundation