Skip to content

Instantly share code, notes, and snippets.

@bdelespierre
Last active August 29, 2015 14:12
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 bdelespierre/99fae6c31285c47a6679 to your computer and use it in GitHub Desktop.
Save bdelespierre/99fae6c31285c47a6679 to your computer and use it in GitHub Desktop.
<?php
class Bitfield
{
const FIELD_SIZE = 32;
public static function getDistance(array $a, array $b)
{
$dist = 0;
for ($i=0; $i<static::FIELD_SIZE; $i++) {
if (!isset($a[$i]) && !isset($b[$i]))
continue;
if (!isset($a[$i]))
$dist += static::countNonZero($b[$i]);
elseif (!isset($b[$i]))
$dist += static::countNonZero($a[$i]);
else
$dist += static::countNonZero($a[$i] ^ $b[$i]);
}
return $dist;
}
public static function getSimilarity(array $a, array $b)
{
$iden = 0;
foreach($a as $i => $v)
if (isset($b[$i]))
$iden += static::countNonZero($a[$i] & $b[$i]);
return $iden;
}
public static function countNonZero($num)
{
if ($num == 0)
return 0;
$res = 0;
do {
$num &= $num -1;
$res += 1;
} while($num);
return $res;
}
public static function bitfieldToHash(array $bitfield)
{
for ($i=0; $i<static::FIELD_SIZE; $i++)
empty($bitfield[$i]) && $bitfield[$i] = 0;
ksort($bitfield); // thanks Obama!
array_unshift($bitfield, 'N*');
return base64_encode(call_user_func_array('pack', $bitfield));
}
public static function hashToBitfield($hash)
{
return @unpack('N32', base64_decode($hash)) ?: [];
}
}
$h = Bitfield::bitfieldToHash([1 => 2, 10 => 33, 31 => 123]);
$b = Bitfield::hashToBitfield($h);
var_dump( $h, $b );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment