MediaWiki  master
ScrambleMapping.php
Go to the documentation of this file.
1 <?php
2 
4 
32 class ScrambleMapping implements SerialMapping {
45  private const GENERATORS = [
46  [ 56, 97 ],
47  [ 511, 887 ],
48  [ 5203, 9013 ],
49  [ 51947, 90001 ],
50  [ 519612, 900001 ],
51  [ 5196144, 8999993 ],
52  [ 51961523, 89999999 ],
53  [ 519615218, 899999963 ],
54  [ 5196152444, 9000000043 ],
55  ];
56 
58  private $offset;
59 
61  private $hasGmp;
63  private $hasBcm;
64 
65  public function __construct( $config ) {
66  $this->offset = $config['offset'] ?? 0;
67  $this->hasGmp = extension_loaded( 'gmp' );
68  $this->hasBcm = extension_loaded( 'bcmath' );
69  if ( !$this->hasGmp && !$this->hasBcm ) {
70  throw new \MWException( __CLASS__ . ' requires the bcmath or gmp extension' );
71  }
72  }
73 
74  public function getSerialIdForIndex( int $index ): string {
75  if ( $index <= 0 ) {
76  return (string)$index;
77  }
78  $offset = $this->offset;
79  foreach ( self::GENERATORS as [ $g, $p ] ) {
80  if ( $index - $offset < $p ) {
81  return (string)( $offset + $this->powmod( $g, $index - $offset, $p ) );
82  }
83  $offset += $p - 1;
84  }
85  throw new \MWException( __METHOD__ . ": The index $index is too large" );
86  }
87 
88  private function powmod( $num, $exponent, $modulus ) {
89  if ( $this->hasGmp ) {
90  return \gmp_intval( \gmp_powm( $num, $exponent, $modulus ) );
91  } elseif ( $this->hasBcm ) {
92  return (int)\bcpowmod( (string)$num, (string)$exponent, (string)$modulus );
93  } else {
94  throw new \MWException( __CLASS__ . ' requires the bcmath or gmp extension' );
95  }
96  }
97 }
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition: WebStart.php:88
A mapping which converts sequential input into an output sequence that looks pseudo-random,...
Interface for integer to string mappings for temporary user autocreation.