<commit_before><?php
$rom    = file_get_contents('wizwar2.nes');
$table0 = unpack('C*', substr($rom, 0x1FB8E+16, 5));
$table1 = unpack('C*', substr($rom, 0x1FB6A+16, 128));

/* Set password to decode */
$password = '<PASSWORD>';
$charset  = 'BDGHJKLMNPQRTWXZ';

/* Convert to 4-bit numbers */
$nibbles = Array();
for($n=0; $n<12; ++$n) $nibbles[$n] = strpos($charset, $password[$n]);
/* Merge into 8-bit bytes */
$bytes = Array();
for($n=0; $n<6; ++$n) $bytes[$n] = $nibbles[$n*2+0] * 16 + $nibbles[$n*2+1];

/* Decrypt */
$bytes[0] ^= $bytes[5];
$bytes[3] ^= $bytes[5];
for($n=0; $n<5; ++$n) $bytes[$n] ^= $table0[1 + $n];

$A = $bytes[4] ^ $bytes[0] ^ $bytes[1];
print "A is $A . Reject if >= 62\n";

$bytes[2] ^= $table1[1 + $A*2 + 0];
$bytes[3] ^= $table1[1 + $A*2 + 1];
$crazy = ($bytes[0] ^ $bytes[1] ^ $bytes[2] ^ (($bytes[0] ^ $bytes[1]) >> 4)) & 15;
printf("Crazy = %d Byte3low = %d, these should match\n", $crazy, $bytes[3] & 15);

$values = Array(
  'lives'  => ($bytes[2] >> 4) & 3, //     but store 3 if value is 0
  'weapon' => ($bytes[0] >> 5) & 7, // 67 (die if value is 7)
  'armor'  => ($bytes[0] >> 1) & 3, // 68
  'shield' => ($bytes[0] >> 3) & 3, // 69, but store 255 if value is 3
  'unknown' => ($bytes[3] >> 6) & 3, // EF
  'number_of_item1' => ($bytes[1] >> 6) & 3, // 454[6~
  'number_of_item2' => ($bytes[1] >> 4) & 3, // 455
  'number_of_item3' => ($bytes[3] >> 4) & 3, // 456
  'number_of_item4' => ($bytes[1] >> 2) & 3, // 457
  'number_of_item5' => ($bytes[1] >> 0) & 3, // 458
  'number_of_item6' => ($bytes[2] >> 6) & 3, // 459
  'number_of_item7' => ($bytes[0] >> 0) & 1, // 45D
  'keys' => $bytes[2] & 15, // keys
  'level' => $bytes[4]
);

/* For testing, make a little change */
$values['level'] = 59;

/* Encode the password */

$bytes[5] = 0xFF; // Arbitrarily chosen byte (?)

$bytes[0] = $values['number_of_item7']
          + $values['armor'] * 2
          + $values['shield'] * 8
          + $values['weapon'] * 32;
$bytes[1] = $values['number_of_item5']
          + $values['number_of_item4'] * 4
          + $values['number_of_item2'] * 16
          + $values['number_of_item1'] * 64;
$bytes[2] = $values['keys']
          + $values['lives'] * 16
          + $values['number_of_item6'] * 64;
$bytes[3] = $values['number_of_item3'] * 16
          + $values['unknown'] * 64;

$crazy = ($bytes[0] ^ $bytes[1] ^ $bytes[2] ^ (($bytes[0] ^ $bytes[1]) >> 4)) & 15;
$bytes[3] += $crazy;

$A = $bytes[0] ^ $bytes[1];
$bytes[4] = $A ^ $values['level'];
$A ^= $bytes[4];

print "We got A = $A\n";
$bytes[2] ^= $table1[1 + $A*2 + 0];
$bytes[3] ^= $table1[1 + $A*2 + 1];
for($n=0; $n<5; ++$n) $bytes[$n] ^= $table0[1 + $n];
$bytes[0] ^= $bytes[5];
$bytes[3] ^= $bytes[5];

/* Convert bytes into symbols */
$p = '';
for($n=0; $n<6; ++$n)
{
  $p .= $charset[$bytes[$n] >> 4];
  $p .= $charset[$bytes[$n] & 0xF];
}

/* Print output */
print "Pass: $p\n";<commit_msg>Update the Iron Sword program a bit for tidier code<commit_after><?php
$rom    = file_get_contents('wizwar2.nes');
$table0 = unpack('C*', substr($rom, 0x1FB8E+16, 5));
$table1 = unpack('C*', substr($rom, 0x1FB6A+16, 128));

/* Set password to decode */
$password = '<PASSWORD>';
$charset  = 'BDGHJKLMNPQRTWXZ';

/* Convert to 4-bit numbers */
$nibbles = Array();
for($n=0; $n<12; ++$n) $nibbles[$n] = strpos($charset, $password[$n]);
/* Merge into 8-bit bytes */
$bytes = Array();
for($n=0; $n<6; ++$n) $bytes[$n] = $nibbles[$n*2+0] * 16 + $nibbles[$n*2+1];

/* Decrypt */
print "byte5 = {$bytes[5]}\n";
$bytes[0] ^= $table0[1] ^ $bytes[5];
$bytes[1] ^= $table0[2];
$a = $bytes[0] ^ $bytes[1];
$bytes[4] ^= $table0[5] ^ $a;
$bytes[2] ^= $table0[3] ^ $table1[1 + $bytes[4]*2 + 0];
$bytes[3] ^= $table0[4] ^ $table1[1 + $bytes[4]*2 + 1] ^ $bytes[5];

if((($bytes[3] ^ $a ^ $bytes[2] ^ ($a >> 4)) & 15) != 0) print "Data error\n";

$values = Array(
  'lives'  => ($bytes[2] >> 4) & 3, //     but store 3 if value is 0
  'weapon' => ($bytes[0] >> 5) & 7, // 67 (die if value is 7)
  'armor'  => ($bytes[0] >> 1) & 3, // 68
  'shield' => ($bytes[0] >> 3) & 3, // 69, but store 255 if value is 3
  'unknown' => ($bytes[3] >> 6) & 3, // EF
  'number_of_item1' => ($bytes[1] >> 6) & 3, // 454
  'number_of_item2' => ($bytes[1] >> 4) & 3, // 455
  'number_of_item3' => ($bytes[3] >> 4) & 3, // 456
  'number_of_item4' => ($bytes[1] >> 2) & 3, // 457
  'number_of_item5' => ($bytes[1] >> 0) & 3, // 458
  'number_of_item6' => ($bytes[2] >> 6) & 3, // 459
  'number_of_item7' => ($bytes[0] >> 0) & 1, // 45D
  'keys' => $bytes[2] & 15, // keys
  'level' => $bytes[4]
);

print "Note: Level is {$values['level']}. Reject if >= 62\n";
print "Note: Weapon is {$values['weapon']}. Reject if >= 7\n";


/* For testing, make a little change */
#$values['level'] = 59;

/* Encode the password */

$bytes[0] = $values['number_of_item7']
          + $values['armor'] * 2
          + $values['shield'] * 8
          + $values['weapon'] * 32;
$bytes[1] = $values['number_of_item5']
          + $values['number_of_item4'] * 4
          + $values['number_of_item2'] * 16
          + $values['number_of_item1'] * 64;
$bytes[2] = $values['keys']
          + $values['lives'] * 16
          + $values['number_of_item6'] * 64;
$a = $bytes[0] ^ $bytes[1];
$bytes[3] = $values['number_of_item3'] * 16
          + $values['unknown'] * 64
          + (($a ^ $bytes[2] ^ ($a >> 4)) & 15);
$bytes[4] = $values['level'];

// Byte 5: Any arbitrary byte used for encryption.
#$bytes[5] = $a ^ $bytes[2] ^ $bytes[3] ^ $bytes[4];
print "using byte5 = {$bytes[5]}\n";
$bytes[0] ^= $table0[1] ^ $bytes[5];
$bytes[1] ^= $table0[2];
$bytes[2] ^= $table0[3] ^ $table1[1 + $bytes[4]*2 + 0];
$bytes[3] ^= $table0[4] ^ $table1[1 + $bytes[4]*2 + 1] ^ $bytes[5];
$bytes[4] ^= $table0[5] ^ $a;

/* Convert bytes into symbols */
$p = '';
for($n=0; $n<6; ++$n)
{
  $p .= $charset[$bytes[$n] >> 4];
  $p .= $charset[$bytes[$n] & 0xF];
}

/* Print output */
print "Orig: $password\n";
print "Pass: $p\n";
{'fraction_non_alphanumeric': 0.2756938603868797, 'fraction_numerical': 0.0736753574432296, 'mean_word_length': 3.480783722682743, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '1308139', 'n_tokens_mistral': 2853, 'n_tokens_neox': 2614, 'n_words': 581}