djhackersdev / bemanitools

Runs recent Konami arcade games and emulates various arcade hardware.
The Unlicense
84 stars 16 forks source link

Refactor pcbid generator (clean code reference) #75

Open icex2 opened 3 years ago

icex2 commented 3 years ago

confidential issue because the source asked to not share the snippet in public.

translate the following php code snippet which is based on the implemented from bemanitools (decompiled code) and feed it back to the project. make sure to test the new against the previous implementation (unit test highly adviced).

<?php

class PcbId {

    const HEADER = 0x01;

    public static function generate(?string $id_hex = null): string {

        $id = $id_hex ? hex2bin($id_hex) : random_bytes(8);

        $checksum = self::getChecksum($id);
        return strtoupper(bin2hex(chr(self::HEADER) . $id . chr($checksum)));
    }

    public static function verify(string $input_hex): bool  {

        $input = hex2bin($input_hex);

        $header = substr($input, 0, 1);
        $id = substr($input, 1, 8);
        $checksum = substr($input, -1);

        $expected_checksum = self::getChecksum($id);

        return $header == chr(self::HEADER) && $checksum == chr($expected_checksum);
    }

    private static function getChecksum(string $id): int {

        $checksum = 0;

        $map = [1, 7, 6, 5, 4, 3, 2];

        $length = count($map);

        for($i = 0; $i < $length; $i++) {
            $byte = ord($id[$map[$i]]);
            for($j = 0; $j < 8; $j++) {
                $should_xor = ($checksum ^ ($byte >> $j)) & 1;
                $checksum = $checksum >> 1;
                if($should_xor) $checksum ^= 0x8c;
            }
        }

        return $checksum;
    }

}