PHP version of thumbnail hash calculation needed

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
Klojum Offline
Junior Member
Posts: 22
Joined: Nov 2009
Reputation: 0
Post: #1
I'm looking for a bit of help in translating a C# script into a PHP script/function. I am working on a PHP-tool for enhancing my remote XBMC collection for my standalone mediastreamer.

The big problem is, my limited knowledge of C# is making me unable to translate the C# hashscript into a PHP-function.

This is the code according to one of the XBMC-Wikipages. Unfortunately I'm unable to get past the XOR and other math thingies.

Code:
public string Hash(string input)
{
   char[] chars = input.ToCharArray();
   for (int index = 0; index < chars.Length; index++)
   {
       if (chars[index] <= 127)
       {
          chars[index] = System.Char.ToLowerInvariant(chars[index]);
       }
   }
   input = new string(chars);
   uint m_crc = 0xffffffff;
   byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input);
   foreach (byte myByte in bytes)
   {
       m_crc ^= ((uint)(myByte) << 24);
       for (int i = 0; i < 8; i++)
       {
           if ((System.Convert.ToUInt32(m_crc) & 0x80000000) == 0x80000000)
           {
               m_crc = (m_crc << 1) ^ 0x04C11DB7;
           }
           else
           {
               m_crc <<= 1;
           }
       }
   }
   return String.Format("{0:x8}", m_crc);
}

These are two supposed examples of text strings that should work with this code:
* 123456789 returns 0376e6e7
* F:\Videos\Nosferatu.avi returns 2a6ec78d

Hope anyone can help me out with a "translation" to PHP of this C# routine. Thanks in advance Eek
find quote
spiff Offline
Retired Developer
Posts: 12,386
Joined: Nov 2003
Post: #2
it's not really doing anything fancy. it lowercases ascii values, inits the crc at 0xFFFFFFF and runs the loop. finally it returns the hex string of the result. i don't really write php so you'll spit that out faster than me.
find quote
Nick8888 Offline
Fan
Posts: 716
Joined: Jan 2007
Reputation: 0
Post: #3
I assume you have read this javascript example. http://forum.xbmc.org/showthread.php?tid=58389

Post your code if you achieve this as I wouldn't mind adding it to the mediafrontpage project in the future.
find quote
opdenkamp Offline
Team-XBMC PVR Developer
Posts: 2,230
Joined: Feb 2009
Reputation: 29
Location: Heerlen, The Netherlands
Post: #4
it should be something like this:
Code:
function calculate_hash($input)
{
    $chars = strtolower($input);
    $crc = 0xffffffff;
    
    for ($ptr = 0; $ptr < strlen($chars); $ptr++)
    {
        $chr = ord($chars[$ptr]);
        $crc ^= $chr << 24;
        
        for (int $i = 0; $i < 8; $i++)
        {
            if ($crc & 0x80000000 == 0x80000000)
            {
                $crc = ($crc << 1) ^ 0x04C11DB7;
            }
            else
            {
                $crc <<= 1;
            }
        }
    }
    
    return $crc;
}
just typed this in a text editor without testing anything, so you'll probably have to change a couple of things, but this should give you a start.

opdenkamp / dushmaniac

xbmc-pvr [Eden-PVR builds] [now included in mainline XBMC, so no more source link here :)]
personal website: [link]

Found a problem with PVR? Report it on Trac, under "PVR - core components". Please attach the full debug log.

If you like my work, please consider donating to me and/or Team XBMC.
find quote
rhormaza Offline
Junior Member
Posts: 7
Joined: Jan 2011
Reputation: 0
Post: #5
I can confirm that the php function works!
the only change I had to do was the following line:

-if ($crc & 0x80000000 == 0x80000000)
+if ($crc & 0x80000000)

Thanks, it was very helpful Wink
find quote
MakuraRyu Offline
Junior Member
Posts: 3
Joined: Feb 2011
Reputation: 1
Post: #6
Here's the same PHP function but has the benefit that it's properly formatted. Please note it does use the GNU Multiple Precision for formatting (negative) numbers. Otherwise all negatives (PHP doesn't have unsigned integers natively) will hash incorrectly.
Code:
function thumbnailHash($input) {
    $chars = strtolower($input);
    $crc = 0xffffffff;
    for ($ptr = 0; $ptr < strlen($chars); $ptr++) {
        $chr = ord($chars[$ptr]);
        $crc ^= $chr << 24;
        for ($i=0; $i<8; $i++){
            if ($crc & 0x80000000) {
                $crc = ($crc << 1) ^ 0x04C11DB7;
            } else {
                $crc <<= 1;
            }
        }
    }
    //Formatting the output in a 8 character hex
    if ($crc>=0){
        //positive results will hash properly without any issues
        return sprintf("%08s",sprintf("%x",sprintf("%u",$crc)));
    } else {
        /*
         * negative values will need to be properly converted to
         * unsigned integers before the value can be determined.
         */
        return sprintf("%08s",gmp_strval(gmp_init(sprintf("%u",$crc)),16));
    }
}
find quote
DKreeK Offline
Junior Member
Posts: 21
Joined: Jan 2010
Reputation: 0
Post: #7
Hi,

I have an Apache/PHP server but without the GMP extension. There is an equivalent function to gmp_init and gmp_strval ??

Thank you
find quote
narfight Offline
Junior Member
Posts: 2
Joined: Oct 2011
Reputation: 0
Post: #8
DKreeK Wrote:Hi,

I have an Apache/PHP server but without the GMP extension. There is an equivalent function to gmp_init and gmp_strval ??

Thank you

Of course, sorry for the delay Rolleyes

Code:
function thumbnailHash($input)
{
    $chars = strtolower($input);
    $crc = 0xffffffff;
    for ($ptr = 0; $ptr < strlen($chars); $ptr++)
    {
        $chr = ord($chars[$ptr]);
        $crc ^= $chr << 24;
        for ($i=0; $i<8; $i++)
        {
            if ($crc & 0x80000000)
            {
                $crc = ($crc << 1) ^ 0x04C11DB7;
            }
            else
            {
                $crc <<= 1;
            }
        }
    }
    //Formatting the output in a 8 character hex
    if ($crc>=0)
    {
        return sprintf("%08s",sprintf("%x",sprintf("%u",$crc)));
    }
    else
    {
        $Source = sprintf('%b', $crc);
        $StrConvert = "";
        while ($Source <> "")
        {
            $Digit = substr($Source, -4, 4);
            $Source = substr($Source, 0, -4);
            $StrConvert = base_convert($Digit, 2, 16) . $StrConvert;
        }
        
        return $StrConvert;
    }
}
find quote
tamplan Offline
Member
Posts: 93
Joined: Dec 2009
Reputation: 0
Location: France
Post: #9
Hi,

I have trouble with the previous code and made the following updated with system in 32bits and 64bits :
Code:
private function _get_hash($file_path)
  {
    $chars = strtolower($file_path);
    $crc = 0xffffffff;

    for ($ptr = 0; $ptr < strlen($chars); $ptr++)
    {
      $chr = ord($chars[$ptr]);
      $crc ^= $chr << 24;

      for ((int) $i = 0; $i < 8; $i++)
      {
        if ($crc & 0x80000000)
        {
          $crc = ($crc << 1) ^ 0x04C11DB7;
        }
        else
        {
          $crc <<= 1;
        }
      }
    }

    // Système d'exploitation en 64 bits ?
    if (strpos(php_uname('m'), '_64') !== false)
    {

            //Formatting the output in a 8 character hex
            if ($crc>=0)
            {
                $hash = sprintf("%16s",sprintf("%x",sprintf("%u",$crc)));
            }
            else
            {
                $source = sprintf('%b', $crc);

                $hash = "";
                while ($source <> "")
                {
                    $digit = substr($source, -4);
                    $hash = dechex(bindec($digit)) . $hash;
                    $source = substr($source, 0, -4);
                }
            }
            $hash = substr($hash, 8);
    }
    else
    {
            //Formatting the output in a 8 character hex
            if ($crc>=0)
            {
                $hash = sprintf("%08s",sprintf("%x",sprintf("%u",$crc)));
            }
            else
            {
                $source = sprintf('%b', $crc);

                $hash = "";
                while ($source <> "")
                {
                    $digit = substr($source, -4);
                    $hash = dechex(bindec($digit)) . $hash;
                    $source = substr($source, 0, -4);
                }
            }
    }

    return $hash;
  }

Hope this helps and thanks to narfight.
find quote
baderj Offline
Junior Member
Posts: 9
Joined: Feb 2012
Reputation: 0
Post: #10
I added Perl and Python versions of the XBMC CRC code to the WIKI:
http://wiki.xbmc.org/index.php?title=Thu...ample_Code

Thanks to dushmaniac for providing the PHP version.
find quote