Search code examples
phparrayshexrgbchecksum

hexa string array editting in php


I am trying to get RGB-values to a tablet from my website. The tablet only accepts SICP commands. Currently I am using netcat to establish connection like this:

$cmd = 'echo -n -e "\x09\x01\x00\xf3\x01\xff\x80\x00'.$checksum.'" | nc '.$ip.' '.$port;
                shell_exec($cmd);
                echo $cmd;

This works for the tablet, but I am still unable to make variables for the 3 RGB values because of my checksum calculator requiring hexa format. I can make hexa array in PHP("hexstrcomp") where last 4 values are the RGB and checksum.

$hexshowndec = array("09","01","00","f3", "01", "ff", "80", "00", "00");     
$hexstrcomp = array("\x09","\x01","\x00","\xf3","\x01","\xff","\x80","\x00","\x00");
                for ($i = 0; $i < 8; $i++)  // 8 for message length before checksum
                {
                    $byte = $hexstrcomp[$i];
                    $hexstrcomp[8] = $hexstrcomp[8] ^ ord($byte);
                    echo "Current checksum: " . sprintf("%02x", $hexstrcomp[8]) . "<br>"; // 0x23
                }
                echo "Checksum: " . sprintf("%02x", $hexstrcomp[8]);

                $cmd = 'echo -n -e "\x' . $hexshowndec[0]
                        . '\x' . $hexshowndec[1]                             
                        . '\x' . $hexshowndec[2] 
                        . '\x' . $hexshowndec[3] 
                        . '\x' . $hexshowndec[4] 
                        . '\x' . $hexshowndec[5] 
                        . '\x' . $hexshowndec[6] 
                        . '\x' . $hexshowndec[7] 
                        . '\x' . sprintf("%02x", $hexstrcomp[8])
                        . '" | nc '.$ip.' '.$port;
                shell_exec($cmd);
                echo "<p>Orange!</p>";

How can I change value for hexstrcomp[5] for example, so I can still use my checksum succesfully? Tried following causing checksum to fail:

$hexshowndec[6] = sprintf("%02x", $hexstrcomp[6]); //gets this done
$hexstrcomp[6] = "\x00";    // works, but need variable for 00 part
$hexstrcomp[6] = "\x{$hexshowndec[6]}";    // fails
$hexstrcomp[6] = "\x" . $hexshowndec[6];    // fails

Solution

  • Take $hexshowndec[6] turn it into decimal with hexdec() then turn it into a character (a raw byte in your case) with chr()

    $hexstrcomp[6] = chr( hexdec( $hexshowndec[6] ) );
    

    Actually you can create $hexstrcomp programmatically from $hexshowndec with the same approach and a foreach loop:

    $hexshowndec = array("09", "01", "00", "f3", "01", "ff", "80", "00", "00"); 
    $hexstrcomp = array();
    foreach( $hexshowndec as $hsd ) {
        $hexstrcomp[] = chr( hexdec ( $hsd ) );
    }
    

    ...or with a shorter onliner:

    $hexshowndec = array("09", "01", "00", "f3", "01", "ff", "80", "00", "00"); 
    $hexstrcomp = str_split( pack( "H*", implode( '', $hexshowndec ) ) );
    

    Your script for an arbitrary-lenght input:

    $hexshowndec = array( "09", "01", "00", "f3", "01", "ff", "80", "00", "00");     
    $hexstrcomp = str_split( pack( "H*", implode( '', $hexshowndec ) ) );
    
    // The last byte is for checksum and initially set to 0x00
    $n = count( $hexshowndec ) - 1;
    
    for( $i = 0; $i < $n; $i++ )
    {
        $byte = $hexstrcomp[ $i ];
        $hexstrcomp[ $n ] = $hexstrcomp[ $n ] ^ ord( $byte );
    }
    
    $cmd = 'echo -n -e "';
    for( $i = 0; $i < $n; $i++ )
    {
        $cmd .= '\x' . $hexshowndec[ $i ];
    }
    
    $cmd .= '\x' . sprintf( "%02x", $hexstrcomp[ $n ] );  
    $cmd .= '" | nc '.$ip.' '.$port;
    
    shell_exec( $cmd );