Avatar billede drdal Nybegynder
09. april 2007 - 17:09 Der er 18 kommentarer og
1 løsning

SMS, hjælp til at decode PDU

Hej Eksperter

Jeg er ved at lave et program, der via et GSM modem sender og modtager SMS beskeder i PDU format.

Jeg har med møje og besvær konverteret PDU strengen så jeg nu kun har selve beskeden uden afsender, tid/dato m.m.

Jeg har læst et svar givet af arne_v, der indkoder en streng til PDU: http://www.eksperten.dk/spm/555194
jeg har så brug for det modsatte, altså at dekode PDU tilbage til  en streng.

eks.
E8329BFD4697D9EC37 skal blive til hellohello

har forsøgt at vende arne_v's svar men kører konstant fast...
http://www.eksperten.dk/spm/555194

nogen der kan hjælpe?

se også dette link omkring bit konvertering:
http://www.dreamfabric.com/sms/hello.html
Avatar billede arne_v Ekspert
09. april 2007 - 17:39 #1
try this:

using System;
using System.Text;

public class BitFun
{
    private static void From8To7(byte[] b, ref int boffset, byte[] res, ref int resoffset)
    {
        long temp = 0;
        int blen = Math.Min(b.Length - boffset, 8);
        for(int i = 0; i < blen; i++)
        {
            temp |= (((long)b[boffset + i]) << (i * 7));
        }
        boffset += blen;
        int reslen = (blen*7+7)/8;
        for(int j = 0; j < reslen; j++)
        {
            res[resoffset + j] = (byte)((temp >> (j * 8))& 0xFF);
        }
        resoffset += reslen;
    }
    private static void From7To8(byte[] b, ref int boffset, byte[] res, ref int resoffset)
    {
        long temp = 0;
        int blen = Math.Min(b.Length - boffset, 7);
        for(int i = 0; i < blen; i++)
        {
            temp |= (((long)b[boffset + i]) << (i * 8));
        }
        boffset += blen;
        int reslen = (blen*8+6)/7;
        for(int j = 0; j < reslen; j++)
        {
            res[resoffset + j] = (byte)((temp >> (j * 7))& 0x7F);
        }
        resoffset += reslen;
    }
    public static byte[] Encode(string s)
    {
        byte[] b = Encoding.ASCII.GetBytes(s);
        int boffset = 0;
        byte[] res = new byte[(b.Length*7+7)/8];
        int resoffset = 0;
        while(boffset < b.Length)
        {
            From8To7(b, ref boffset, res, ref resoffset);
        }
        return res;
    }
    public static string Decode(byte[] b)
    {
        int boffset = 0;
        byte[] res = new byte[(b.Length*8+6)/7];
        int resoffset = 0;
        while(boffset < b.Length)
        {
            From7To8(b, ref boffset, res, ref resoffset);
        }
        int n = resoffset;
        while((n > 0) && (res[n-1] == 0)) n--;
        return Encoding.ASCII.GetString(res, 0, n);
    }
    public static void Main(string[] args)
    {
        byte[] data = Encode("hellohello");
        for(int k = 0; k < data.Length; k++)
        {
            Console.Write(String.Format("{0:X2} ",data[k]));
        }
        Console.WriteLine();
        Console.WriteLine(Decode(data));
        Console.ReadLine();
    }
}
Avatar billede arne_v Ekspert
09. april 2007 - 17:49 #2
der kom et andet spoergsmaal med decode en maaneds tid senere, hvor jeg lavede noget
kode - og et par aar efter kom der saa et tredie spoergsmaal fordi der var en
lille bug i min Decode - ovenstaaende skulle vaere med bug fix
Avatar billede drdal Nybegynder
10. april 2007 - 08:57 #3
Det er simpelhen for vildt! super! jeg tester her senere på dagen! send svar
Avatar billede drdal Nybegynder
10. april 2007 - 11:30 #4
Jeg er ved at teste det nu, men kan ikke få Decode() til at returnere noget læseligt.. Jeg anvender den nok forkert?

string Besked = "E8329BFD4697D9EC37"; //hellohello

byte[] data = new byte[Besked.Length];
           
for (int k = 0; k < Besked.Length; k++)
    {
        data[k] = Convert.ToByte(Besked[k]);
    }
Besked = Decode(data);

MessageBox.Show(Besked);
Avatar billede arne_v Ekspert
10. april 2007 - 15:07 #5
ja

proev

byte[] data = { (byte)0xE8, (byte)0x32, ... };
Avatar billede drdal Nybegynder
10. april 2007 - 15:24 #6
ja ok, det kan jeg godt se, men min "Besked" indeholder i den endelige kode noget dynamisk.. altså teksten fra en modtaget SMS i hex og den vil jeg så gerne have lavet om til en læselig string. Kan jeg anvende din Decode() til det, eller hvad er det den returnere?
Avatar billede arne_v Ekspert
10. april 2007 - 15:51 #7
ja

men har du ikke et byte[] i den endelige kode ?
Avatar billede arne_v Ekspert
10. april 2007 - 15:56 #8
ellers har jeg noget kode til at konvertere fra hex streng til byte array
Avatar billede drdal Nybegynder
10. april 2007 - 16:43 #9
okay! du må meget gerne smide kodet her ind.. jeg for lige en kollega til at se på det i morgen også, det kan være han kan hjælpe mig. jeg vender tilbage i morgen, tak for din tålmodighed! :D
Avatar billede arne_v Ekspert
10. april 2007 - 17:00 #10
public static string ToHex(byte[] ba)
        {
            StringBuilder sb = new StringBuilder(2 * ba.Length);
            for(int i = 0; i < ba.Length; i++)
            {
                sb.Append(ba[i].ToString("X2"));
            }
            return sb.ToString();
        }
        public static byte[] FromHex(string s)
        {
            byte[] ba = new byte[s.Length/2];
            for(int i = 0; i < ba.Length; i++)
            {
                ba[i] = byte.Parse(s.Substring(2 * i, 2), NumberStyles.HexNumber);
            }
            return ba;
        }
Avatar billede arne_v Ekspert
10. april 2007 - 17:05 #11
og et svar
Avatar billede drdal Nybegynder
11. april 2007 - 10:42 #12
Tusind tak for den sublime hjælp! Jeg er som altid mundlam over din kunnen!
Avatar billede drdal Nybegynder
11. april 2007 - 10:53 #13
Og så må jeg lige tilføje at nu virker det FA...! lige bortset fra æøå, men det skulle være til at overkomme, måske!
Avatar billede arne_v Ekspert
11. april 2007 - 16:29 #14
proev og erstat

Encoding.ASCII

med

Encoding.Default

eller

Encoding.UTF8

og se om de danske tegn kommer med saa
Avatar billede drdal Nybegynder
11. april 2007 - 16:37 #15
Det er nu testet, men den viser stadig en mærkelig firkant i stedet
Avatar billede drdal Nybegynder
11. april 2007 - 17:03 #16
Har løst det med lidt slam-kode:

            byte ae = 0x1d; // æ
            byte AE = 0x1c; // Æ
           
            byte oe = 0x0c; // ø
            byte OE = 0x0b; // Ø
           
            byte aa = 0x0e; // å
            byte AA = 0x0f; // Å

            Besked = Besked.Replace(Convert.ToChar(ae).ToString(), "æ");
            Besked = Besked.Replace(Convert.ToChar(AE).ToString(), "Æ");
            Besked = Besked.Replace(Convert.ToChar(oe).ToString(), "ø");
            Besked = Besked.Replace(Convert.ToChar(OE).ToString(), "Ø");
            Besked = Besked.Replace(Convert.ToChar(aa).ToString(), "å");
            Besked = Besked.Replace(Convert.ToChar(AA).ToString(), "Å");
Avatar billede arne_v Ekspert
13. april 2007 - 03:43 #17
her er en Encoding klasse som gør det samme:

using System;
using System.Text;

namespace E
{
    public class SMSPDUEncoding : Encoding
    {
        public override int GetMaxByteCount(int charCount)
        {
            return charCount;
        }
        public override int GetMaxCharCount(int byteCount)
        {
            return byteCount;
        }
        public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars,    int charIndex)
        {
            for(int i = 0; i < byteCount; i++)
            {
                if(bytes[byteIndex + i] == 0x1C)
                {
                    chars[charIndex + i] = 'Æ';
                }
                else if(bytes[byteIndex + i] == 0x0B)
                {
                    chars[charIndex + i] = 'Ø';
                }
                else if(bytes[byteIndex + i] == 0x0F)
                {
                    chars[charIndex + i] = 'Å';
                }
                else if(bytes[byteIndex + i] == 0x1D)
                {
                    chars[charIndex + i] = 'æ';
                }
                else if(bytes[byteIndex + i] == 0x0C)
                {
                    chars[charIndex + i] = 'ø';
                }
                else if(bytes[byteIndex + i] == 0x0E)
                {
                    chars[charIndex + i] = 'å';
                }
                else if(bytes[byteIndex + i] >= 32 && bytes[byteIndex + i] <= 126)
                {
                    chars[charIndex + i] = (char)bytes[byteIndex + i];
                }
                else
                {
                    throw new ArgumentException("Unsupported byte");
                }
            }
            return byteCount;   
        }
        public override int GetCharCount(byte[] bytes,    int index,int count)
        {
            return count;
        }
        public override int GetBytes(char[] chars,    int charIndex, int charCount,     byte[] bytes, int byteIndex)
        {
            for(int i = 0; i < charCount; i++)
            {
                if(chars[charIndex + i] == 'Æ')
                {
                    bytes[byteIndex + i] = 0x1C;
                }
                else if(chars[charIndex + i] == 'Ø')
                {
                    bytes[byteIndex + i] = 0x0B;
                }
                else if(chars[charIndex + i] == 'Å')
                {
                    bytes[byteIndex + i] = 0x0F;
                }
                else if(chars[charIndex + i] == 'æ')
                {
                    bytes[byteIndex + i] = 0x1D;
                }
                else if(chars[charIndex + i] == 'ø')
                {
                    bytes[byteIndex + i] = 0x0C;
                }
                else if(chars[charIndex + i] == 'å')
                {
                    bytes[byteIndex + i] = 0x0E;
                }
                else if(chars[charIndex + i] >= ' ' && chars[charIndex + i] <= '~')
                {
                    bytes[byteIndex + i] = (byte)chars[charIndex + i];
                }
                else
                {
                    throw new ArgumentException("Unsupported char");
                }
            }
            return charCount;
        }
        public override int GetByteCount(char[] chars,    int index, int count)
        {
            return count;           
        }
    }
    public class MainClass
    {
        public static void Main(string[] args)
        {
            string s = "ABCabcÆØÅæøå";
            Encoding enc = new SMSPDUEncoding();
            byte[] b = enc.GetBytes(s);
            Console.WriteLine(b[6] + " " + b[7] + " " + b[8] +
                              " " + b[9] + " " + b[10] + " " + b[11]);
            string s2 = enc.GetString(b);
            Console.WriteLine(s2);
            Console.ReadLine();
        }
    }
}
Avatar billede drdal Nybegynder
13. april 2007 - 13:39 #18
okay okay!! Hvordan kan jeg anvende det i sammenhæng med encode() fra tidligere?
Avatar billede drdal Nybegynder
13. april 2007 - 14:35 #19
Har fået det til at virke:

public byte[] Encode(string s)
        {
            byte[] b = enc.GetBytes(s);
            //byte[] b = Encoding.ASCII.GetBytes(s); // Encoding.ASCII
            int boffset = 0;
            byte[] res = new byte[(b.Length * 7 + 7) / 8];
            int resoffset = 0;
            while (boffset < b.Length)
            {
                From8To7(b, ref boffset, res, ref resoffset);
            }
            return res;
        }
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester