yojimbos_law icon

revised and still bad ASH implementation of php's mt_rand()

yojimbos_law | PRO | 06/15/19 02:38:28 PM UTC | 0 ⭐ | 459 👁️ | Never ⏰ | []
text |

2.66 KB

|

None

|

0 👍

/

0 👎

int seed = 2;
int[int] s;
int mt_index = 623;
 //this is a function for 32bit multiplication because ASH doesn't manipulate numbers the way we need.
 int mult32(int a, int b) {
        int product = 0;
        for (int i = 0; i < 32; i++) {
            product += (a <<  i) * (1 & b);
            b >>>= 1;
        }
        return product;
    }
 //this is some linear map that we use in the recursion function.
//except we don't actually use it because php made an oopsie where they look at the lowest bit of the wrong thing.
int A(int x){
	if((x&1) == 0){
		return (x >>> 1);
	}
	else{
		return ((x >>> 1) ^ 2567483615);
	}
}
 //this is the MT recursion function, maybe?
int twist(int m, int u,int v){
	//if done correctly(?):
	//return (m ^ A( ( ( u & 2147483648 ) | ( v & 2147483647 ) ) ));
 	//the way php does it:
	return ( m ^ ( ( ( u & 2147483648 ) | ( v & 2147483647  ) ) >> 1 )  ^ ( ( 4294967295 * ( u & 1 ) ) & 2567483615 ) ) ;
}
 //this is the tempering function. God only knows what it does.
int temper(int x){
	int s_one;
	s_one = s[x];
	s_one ^= (s_one >> 11);
	//s_one ^= ((s_one <<  7)%4294967295) & 2636928640;
	//s_one ^= ((s_one << 15)%4294967295) & 4022730752;
	s_one ^= (s_one <<  7) & 2636928640;
	s_one ^= (s_one << 15) & 4022730752;
	//s_one ^= (((s_one <<  7)<<32)>>>32) & 2636928640;
	//s_one ^= (((s_one << 15)<<)>>32) & 4022730752;
	return ( s_one ^ (s_one >> 18) );
}
  //this is going to actually spit out random numbers in the specified range, allegedly.
int mt_rand(int min, int max){
	mt_index++;
	return (min +  ( max - min + 1 ) * (( temper(mt_index) >> 1 )  / ( 2147483647 + 1.0)))  ;
}
 //this is how mt_srand() converts the seed into a 624 word initial condition.
s[0] = seed & 2147483647;
 for j from 1 to 623{
	//s[j] = ( ( ( 1812433253 * ( s[j-1] ^ ( s[j-1] >> 30 ) ) )   + j ) % 4294967295 ) & 2147483647 ;
	s[j] = ( ( mult32( 1812433253 , ( s[j-1] ^ ( s[j-1] >>> 30 ) ) )   + j ) ) & 2147483647 ;
	//s[j] = ( ( 1812433253 * ( s[j-1] ^ ( s[j-1] >> 30 ) )) + j ) & 2147483647 ;
	//print(s[j]);
}
 //this generates the next 624 terms, which are the first 624 outputs of mt_rand() before tempering, probably? and I don't care about more than that, probably?
for i from 0 to 623{
	s[624+i] = twist(s[397+i],s[i],s[i+1]);
}
 for i from 0 to 10{
	print(mt_rand(0, 100));
}
 /*
output:
 29
66
51
13
83
55
4
27
20
22
2
*/
 /*
output upon commenting out line 62 and uncommenting 61:
27
64
48
58
78
83
67
48
4
72
42
 and all such combinations of comments/uncomments produce one of those two lists.
*/
/*
here's what some php sandbox says it should be: https://imgur.com/8ta2ZmG
*/

Comments