Skip to content

Instantly share code, notes, and snippets.

@jaames
Last active February 1, 2021 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaames/4b81bf46fc8e56b7a4db0fd4ce760f40 to your computer and use it in GitHub Desktop.
Save jaames/4b81bf46fc8e56b7a4db0fd4ce760f40 to your computer and use it in GitHub Desktop.
Example PHP script to decode a KWZ filename
<?php
function decode_filename(string $filename)
{
$bytes = base32_decode($filename);
// Convert to byte string
$bin = join('', array_map('chr', $bytes));
// Unpack data
// Hex FSID (9 bytes, 18 chars) | Creation timestamp (uint32) | Modified timestamp (uint32)
return unpack('H18fsid/Vcreated/Vmodified', $bin);
}
function base32_decode(string $input)
{
// KWZ base32 alphabet
$alphabet = 'cwmfjordvegbalksnthpyxquiz012345';
$inputLength = strlen($input);
// Create zerofilled output buffer
$resultSize = ceil($inputLength / 8) * 5;
$result = array_fill(0, $resultSize, 0);
$resultPtr = 0;
// Decoder state
$shift = 8;
$carry = 0;
for ($i = 0; $i < $inputLength; $i++)
{
$char = $input[$i];
// Ignore padding
if ($char === '=')
continue;
// Check char is in alphabet
else if (!str_contains($alphabet, $char))
throw new Error('Invalid character');
// Decode
$code = strpos($alphabet, $char);
$shift -= 5;
if ($shift > 0)
$carry |= $code << $shift;
else if ($shift < 0)
{
$result[$resultPtr++] = $carry | ($code >> -$shift);
$shift += 8;
$carry = ($code << $shift) & 0xff;
}
else
{
$result[$resultPtr++] = $carry | $code;
$shift = 8;
$carry = 0;
}
}
// Trim
return array_slice($result, 0, $resultPtr);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment