Ady Wicaksono Daily Activities

function convert8bitTo7bit with PHP

with one comment

As per GSM 03.40 we can send up to 140 octets (8-bit data), so if we send 7-bit data (septet) we can send up to 160 7-bit ASCII characters. Few days ago I need a function to convert a string to septet hexadecimal representation with PHP without any luck. I tried googling with keyword “convert 8bit to 7bit PHP”, “convert octet to septet PHP”, and similar keyword with no luck.

So I managed to create my own function that works fine so far (hopefully) (but I don’t care if my algo is not optimal nor bad:)) below:


<?
function strToHex($string)
{
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}
function hexToStr($hex)
{
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2)
    {
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}

function hexbin($hex){
    $bin='';
    for($i=0;$i<strlen($hex);$i++)
        $bin.=str_pad(decbin(hexdec($hex{$i})),4,'0',STR_PAD_LEFT);
       return $bin;
} 

function binhex($bin){
    $hex='';
    for($i=strlen($bin)-4;$i>=0;$i-=4)
        $hex.=dechex(bindec(substr($bin,$i,4)));
   return strrev($hex);
}

function Convert8BitTo7Bit($string){
	// Convert String to Hex first
	// E.g *135# will be converted to 2A 31 33 35 23
	$string = strToHex($string);
	// print   "STR = $string\n";
	$total = "";
	for($i = 0; $i < strlen($string); ){
		// Get 1st character string, it's 2 character hex
		$X = $string[$i++].$string[$i++];
		// Convert it to binary
		$my8bit = hexbin($X);
		//print "(8bit) ==> $my8bit\n";
		// remove left side of octet, it shall be septet
		// e.g 2A in octet is 00101010 (8 bit), remove most left 0 --> 0101010 (7 bit)
		$my7bit = substr($my8bit,1,7);
		//print "(7bit) ==>  $my7bit\n";
        // Concatenate it
		$total = $my7bit.$total;
	}
	// Padding the string
	if(strlen($total) % 8 != 0){
		$p1     = (intval((strlen($total) / 8)) + 1) *  8;
		$total  = str_pad($total,$p1,'0',STR_PAD_LEFT);
	}
	$pad   = 7;
	// Conversion begin
	for($i = strlen($total) - 1; $i >= 0 ; $i--){
		$mypad[$pad--] = $total[$i];
		if($pad < 0 || $i <= 0){
			$pad  = 7;
			$tmp1 = array_reverse($mypad);
			//print_r($tmp1);
			$tmp2 = implode($tmp1);
			$res = binhex($tmp2);
			$result .= "$res";
		}
	}
	return $result;
}


?>


To use that code, we simply call the function like this

print Convert8BitTo7Bit("*135#")."\n";

It will print “AAD8AC3602″ which represent hexcode to be send on top of TP-UD GSM 03.40

Another wxample: we have 160 characters to send like below
“Test SMS content 160 characters will be displayed as 140 octets. Test SMS content 160 characters will be displayed as 140 octets.Test SMS content 160 characters”

With calling

print Convert8BitTo7Bit("Test SMS content 160 characters will be displayed as 140 octets. Test SMS content 160 characters will be displayed as 140 octets.Test SMS content 160 characters");

We get 140 octets/bytes hexadecimal code for this:


d4f29c0e9a36a7a0f1db4d2fbbe9a0980d061aa3c3f2f0985e96cf41f7349b0d129741e4f41cce0ee7cb6450780e8ad160a0f7985ea6cf5d206a794e074d9b53d0f8eda697dd7450cc06038dd16179784c2fcbe7a07b9acd0689cb20727a0e6787f36532283c07c56830d07b4c2fd3e72e6a794e074d9b53d0f8eda697dd7450cc06038dd16179784c2fcbe7

Anyway, there’s 1 thing missing here:
as per GSM 03.38

If the total number of characters to be sent equals (8n 1) where n=1,2,3 etc. then there are 7 spare bits at the end of the message. To avoid the situation where the receiving entity confuses 7 binary zero pad bits as the @ character, the carriage return or character (defined in clause 6.1.1) shall be used for padding in this situation, just as for Cell Broadcast.
If is intended to be the last character and the message (including the wanted ) ends on an octet boundary, then another must be added together with a padding bit 0. The receiving entity will perform the carriage return function twice, but this will not result in misoperation as the definition of in clause 6.1.1 is identical to the definition of .
The receiving entity shall remove the final character where the message ends on an octet boundary with as the last character.

So please fix this function and if the latest one is 0×00, replace it with 0X1A (Carriage Return) ;)

About these ads

Written by adywicaksono

December 24, 2009 at 4:24 pm

One Response

Subscribe to comments with RSS.

  1. Hello, thanks for this PHP function, I wonder if you had coded the reverse function ? If not do you think it is hard job to do ? BR

    Manu

    May 10, 2010 at 10:38 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: