## 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++)
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;
}
if(strlen(\$total) % 8 != 0){
\$p1     = (intval((strlen(\$total) / 8)) + 1) *  8;
}
// Conversion begin
for(\$i = strlen(\$total) - 1; \$i >= 0 ; \$i--){
if(\$pad < 0 || \$i <= 0){
//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 0x00, replace it with 0X1A (Carriage Return) 😉

December 24, 2009 at 4:24 pm

### One Response 