<commit_before><?hh //strict
// Inspired from: www.idontplaydarts.com https://www.idontplaydarts.com/static/ga.php_.txt
class Google_Authenticator {
  public static ImmMap<string, int> $Characters = ImmMap {
    'A' => 0,  'B' => 1, 'C' => 2,  'D' => 3,
    'E' => 4,  'F' => 5, 'G' => 6,  'H' => 7,
    'I' => 8,  'J' => 9, 'K' => 10,  'L' => 11,
    'M' => 12,  'N' => 13, 'O' => 14,  'P' => 15,
    'Q' => 16,  'R' => 17, 'S' => 18,  'T' => 19,
    'U' => 20,  'V' => 21, 'W' => 22,  'X' => 23,
    'Y' => 24,  'Z' => 25, '2' => 26,  '3' => 27,
    '4' => 28,  '5' => 29, '6' => 30,  '7' => 31
  };

  public string $Secret;
  public string $RawSecret;
  public function __construct(string $Secret) {
    $Secret = strtoupper($Secret);
    if (!preg_match('/^[A-Z2-7]+$/', $Secret)) {
      throw new InvalidArgumentException('Invalid Secret provided');
    }
    $Length = strlen($Secret);
    $this->RawSecret = $Secret;
    $this->Secret = '';

    $A = 0;
    $B = 0;

    for($i = 0; $i < $Length; ++$i) {
      $A = ($A << 5) + static::$Characters[$Secret[$i]];
      if (($B += 5) >= 8) {
        $B -= 8;
        $this->Secret .= chr(($A & (0xFF << $B)) >> $B);
      }
    }
    if (strlen($this->Secret) < 8) {
      throw new Exception('Secret is too short');
    }
  }
  public function generate(?float $Time = null): string {
    if ($Time === null) {
      $Time = floor(microtime(true) / 30);
    }
    $Time = pack('N*', 0) . pack('N*', $Time);
    $Hash = hash_hmac('sha1', $Time, $this->Secret, true);

    $HashOffset = ord($Hash[19]) & 0xf;
    $Hash = (
        ((ord($Hash[$HashOffset+0]) & 0x7f) << 24 ) |
        ((ord($Hash[$HashOffset+1]) & 0xff) << 16 ) |
        ((ord($Hash[$HashOffset+2]) & 0xff) << 8 ) |
        (ord($Hash[$HashOffset+3]) & 0xff)
    ) % pow(10, 6);
    return str_pad($Hash, 6, '0', STR_PAD_LEFT);
  }
  // Note: apt-get install qrencode
  public function generateQRCode(string $Title, int $Size = 5): string {
    return shell_exec('qrencode '.escapeshellarg('otpauth://totp/'.$Title.'?secret='.$this->RawSecret). ' -o - -s '.$Size);<commit_msg>Add support for 'Issuer' parameter<commit_after><?hh //strict
// Inspired from: www.idontplaydarts.com https://www.idontplaydarts.com/static/ga.php_.txt
class Google_Authenticator {
  public static ImmMap<string, int> $Characters = ImmMap {
    'A' => 0,  'B' => 1, 'C' => 2,  'D' => 3,
    'E' => 4,  'F' => 5, 'G' => 6,  'H' => 7,
    'I' => 8,  'J' => 9, 'K' => 10,  'L' => 11,
    'M' => 12,  'N' => 13, 'O' => 14,  'P' => 15,
    'Q' => 16,  'R' => 17, 'S' => 18,  'T' => 19,
    'U' => 20,  'V' => 21, 'W' => 22,  'X' => 23,
    'Y' => 24,  'Z' => 25, '2' => 26,  '3' => 27,
    '4' => 28,  '5' => 29, '6' => 30,  '7' => 31
  };

  public string $Secret;
  public string $RawSecret;
  public function __construct(string $Secret) {
    $Secret = strtoupper($Secret);
    if (!preg_match('/^[A-Z2-7]+$/', $Secret)) {
      throw new InvalidArgumentException('Invalid Secret provided');
    }
    $Length = strlen($Secret);
    $this->RawSecret = $Secret;
    $this->Secret = '';

    $A = 0;
    $B = 0;

    for($i = 0; $i < $Length; ++$i) {
      $A = ($A << 5) + static::$Characters[$Secret[$i]];
      if (($B += 5) >= 8) {
        $B -= 8;
        $this->Secret .= chr(($A & (0xFF << $B)) >> $B);
      }
    }
    if (strlen($this->Secret) < 8) {
      throw new Exception('Secret is too short');
    }
  }
  public function generate(?float $Time = null): string {
    if ($Time === null) {
      $Time = floor(microtime(true) / 30);
    }
    $Time = pack('N*', 0) . pack('N*', $Time);
    $Hash = hash_hmac('sha1', $Time, $this->Secret, true);

    $HashOffset = ord($Hash[19]) & 0xf;
    $Hash = (
        ((ord($Hash[$HashOffset+0]) & 0x7f) << 24 ) |
        ((ord($Hash[$HashOffset+1]) & 0xff) << 16 ) |
        ((ord($Hash[$HashOffset+2]) & 0xff) << 8 ) |
        (ord($Hash[$HashOffset+3]) & 0xff)
    ) % pow(10, 6);
    return str_pad($Hash, 6, '0', STR_PAD_LEFT);
  }
  // Note: apt-get install qrencode
  public function generateQRCode(string $Title, string $Issuer, int $Size = 5): string {
    return shell_exec('qrencode '.escapeshellarg('otpauth://totp/'.$Title.'?secret='.$this->RawSecret.'&issuer='.$Issuer). ' -o - -s '.$Size);
{'fraction_non_alphanumeric': 0.2461212976022567, 'fraction_numerical': 0.0460742830277386, 'mean_word_length': 2.627450980392157, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 87, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3463271', 'n_tokens_mistral': 1865, 'n_tokens_neox': 1686, 'n_words': 401}