2009-07-08 17 views
0

Ich versuche, ein UDP-Paket von Bytes entsprechend den Zahlen 1-1000 in Folge zu senden. Wie konvertiere ich jede Zahl (1,2,3,4, ..., 998,999,1000) in die Mindestanzahl von Bytes und setze sie in eine Reihenfolge, die ich als UDP-Paket senden kann?C# - Konvertieren einer Sequenz von Zahlen in Bytes

Ich habe das folgende ohne Erfolg versucht. Jede Hilfe würde sehr geschätzt werden!

List<byte> byteList = new List<byte>(); 

     for (int i = 1; i <= 255; i++) 
     { 
      byte[] nByte = BitConverter.GetBytes((byte)i); 
      foreach (byte b in nByte) 
      { 
       byteList.Add(b); 
      } 
     } 

     for (int g = 256; g <= 1000; g++) 
     { 
      UInt16 st = Convert.ToUInt16(g); 
      byte[] xByte = BitConverter.GetBytes(st); 
      foreach (byte c in xByte) 
      { 
       byteList.Add(c); 
      } 
     } 


     byte[] sendMsg = byteList.ToArray(); 

Vielen Dank.

+5

riecht wie Hausaufgaben. Wenn ja, bitte entsprechend markieren. – zvolkov

+0

versuchen Sie die 7-Bit-codierte Int. schau dir meine Antwort unten an. –

Antwort

1

Ein Byte kann nur 256 verschiedene Werte enthalten, sodass Sie die Zahlen über 255 nicht in einem Byte speichern können. Der einfachste Weg wäre die Verwendung von short, also 16 Bit. Wenn Sie wirklich Platz sparen müssen, können Sie 10-Bit-Nummern verwenden und diese in ein Byte-Array packen (10 Bit = 2^10 = 1024 mögliche Werte).

+0

Ich muss Bytes verwenden. Um ein UDP-Paket zu senden, muss ein Byte [] als Nachricht gesendet werden. Kannst du mir bitte sagen, wie man jede Zahl als Bytes ausdrückt? Ich verstehe, dass es eine Logik für Zahlen über 255 geben muss. Vielen Dank im Voraus! –

+0

Wenn Sie _sure_ sind, müssen Sie nie etwas über 1024 senden, Sie können mit 10 Bits pro Wert auskommen, was zu 1250 Bytes führt, was ungefähr 31% der naiven Methode ist, jedes int als 4 Bytes zu senden. Möchten Sie ein Beispiel dafür? – driis

+0

Driis, ja bitte. Ich benötige jedoch die minimale Anzahl von Bits pro Wert und 10 Bits verwende 2 Bytes für jeden Wert. –

6

Sie müssen verwenden:

BitConverter.GetBytes(INTEGER); 
+1

Ich denke, dass Sie den Punkt vermissen, dass er die Zahlen in einer minimalen Anzahl von Bytes insgesamt packen muss. – driis

+0

driis, siehe Matts Antwort unten: http://stackoverflow.com/questions/1099691/c-converting-a-sequence-of-number-into-bytes/1099915#1099915 –

+0

Moayad, werfen Sie einen Blick auf meine Antwort :) –

0

Naiv (auch ungetestet):

List<byte> bytes = new List<byte>(); 

for (int i = 1; i <= 1000; i++) 
{ 
    byte[] nByte = BitConverter.GetBytes(i); 
    foreach(byte b in nByte) bytes.Add(b); 
} 

byte[] byteStream = bytes.ToArray(); 

Werden Sie geben einen Strom von Bytes jede Gruppe von 4 Bytes waren eine Zahl [1, 1000 ].


Sie könnten versucht sein, einige Arbeit zu tun, so dass ich < 256 ein einziges Byte nehmen, i < 65535 zwei Bytes nehmen, etc. Jedoch wenn Sie das tun Sie nicht die Werte aus der lesen kann Strom. Stattdessen würden Sie Längencodierung oder Sentinel-Bits oder etwas Ähnliches hinzufügen.

Ich würde sagen, nicht. Komprimieren Sie einfach den Stream, indem Sie entweder eine integrierte Klasse verwenden oder eine Huffman encoding Implementierung implementieren, indem Sie einen vereinbarten Satz von Frequenzen verwenden.

+0

Ich denke, das ist auf der richtigen Spur, aber jede Zahl muss in der minimalen Anzahl von Bytes ausgedrückt werden. (dh: Nummern 1-255 benötigen nur 1 Byte). Irgendwelche Ideen? –

+1

Sie müssen Sentinels einschließen, wenn Sie tatsächlich auf die minimale Kodierung in der von Ihnen gewünschten Weise reduzieren. Dies führt nicht notwendigerweise zu einer Verringerung der Gesamtgröße. Ich werde in einer Sekunde mit einem besseren, aber anderen Ansatz aktualisieren. –

+0

Kevins Lösung erzeugt einen Gesamtstrom von 4000 Bytes, wenn ich wirklich einen kleineren Stream brauche. Etwas wie 255 + 2x (1000-255) = 1745 Bytes. Irgendwelche Gedanken? –

3

Denken Sie darüber nach, wie Sie sich den Unterschied zu erkennen zwischen der Lage sein:

260, 1 -> 0x1, 0x4, 0x1 
1, 4, 1 -> 0x1, 0x4, 0x1 

Wenn Sie ein Byte für die Zahlen für die Zahlen bis zu 255 und zwei Bytes verwenden 256-1000, werden Sie nicht in der Lage sein, am anderen Ende auszuarbeiten, welche Nummer welchem ​​entspricht.

Wenn Sie sie nur wie beschrieben verschlüsseln müssen, ohne sich Gedanken darüber machen zu müssen, wie sie entschlüsselt werden, dann klopft es mir auf eine erfundene Hausaufgabe oder einen Test, und ich bin nicht geneigt, es für Sie zu lösen.

+0

Sicher kannst du, verwenden Sie einfach 7-Bit-codierte Ganzzahlen. Es ist ein kleiner Trick, der in den BinaryReader/Writers zum Codieren der Länge einer Zeichenfolge verwendet wird. –

+2

Ich weiß, dass ich möchte, dass der Fragesteller über die Antwort nachdenkt, denn das ist der Punkt seiner Hausaufgaben. –

2

Ich glaube, Sie suchen nach etwas entlang der Linien eines 7-Bit-codierten integer:

protected void Write7BitEncodedInt(int value) 
{ 
    uint num = (uint) value; 
    while (num >= 0x80) 
    { 
     this.Write((byte) (num | 0x80)); 
     num = num >> 7; 
    } 
    this.Write((byte) num); 
} 

(entnommen aus System.IO.BinaryWriter.Write(String)).

Die Rückseite ist in der System.IO.BinaryReader Klasse gefunden und sieht ungefähr so ​​aus:

protected internal int Read7BitEncodedInt() 
{ 
    byte num3; 
    int num = 0; 
    int num2 = 0; 
    do 
    { 
     if (num2 == 0x23) 
     { 
      throw new FormatException(Environment.GetResourceString("Format_Bad7BitInt32")); 
     } 
     num3 = this.ReadByte(); 
     num |= (num3 & 0x7f) << num2; 
     num2 += 7; 
    } 
    while ((num3 & 0x80) != 0); 
    return num; 
} 

Ich hoffe, dass dies nicht Hausaufgaben, auch wenn wirklich, wie es ist riecht.

EDIT:

Ok, so sie alle zusammen für Sie zu setzen:

using System; 
using System.IO; 

namespace EncodedNumbers 
{ 
    class Program 
    { 
     protected static void Write7BitEncodedInt(BinaryWriter bin, int value) 
     { 
      uint num = (uint)value; 
      while (num >= 0x80) 
      { 
       bin.Write((byte)(num | 0x80)); 
       num = num >> 7; 
      } 
      bin.Write((byte)num); 
     } 


     static void Main(string[] args) 
     { 
      MemoryStream ms = new MemoryStream(); 
      BinaryWriter bin = new BinaryWriter(ms); 

      for(int i = 1; i < 1000; i++) 
      { 
       Write7BitEncodedInt(bin, i); 
      } 

      byte[] data = ms.ToArray(); 
      int size = data.Length; 
      Console.WriteLine("Total # of Bytes = " + size); 

      Console.ReadLine(); 
     } 
    } 
} 

Die Gesamtgröße ich erhalte, ist 1871 Bytes für Zahlen 1-1000. Btw, könnten Sie einfach angeben, ob dies Hausaufgaben sind? Natürlich werden wir immer noch auf beiden Wegen helfen. Aber wir würden viel lieber versuchen Sie ein wenig härter, so dass Sie tatsächlich für sich selbst lernen können.

EDIT # 2:

Wenn Sie nur ihnen die Fähigkeit zu ignorieren wollen packen sie wieder zu entschlüsseln, können Sie etwas tun können:

protected static void WriteMinimumInt(BinaryWriter bin, int value) 
    { 
     byte[] bytes = BitConverter.GetBytes(value); 
     int skip = bytes.Length-1; 
     while (bytes[skip] == 0) 
     { 
      skip--; 
     } 
     for (int i = 0; i <= skip; i++) 
     { 
      bin.Write(bytes[i]); 
     } 
    } 

Diese alle Bytes ignoriert, die Null sind (von MSB zu LSB). Also für 0-255 wird es ein Byte verwenden. Wie an anderer Stelle angegeben, können Sie die Daten nicht dekodieren, da der Stream jetzt mehrdeutig ist. Als Nebenbemerkung beschränkt sich dieser Ansatz auf 1743 Byte (im Gegensatz zu 1871 mit 7-Bit-Codierung).

+0

Erich, wie nutze ich Ihre Funktionen für alle Nummern 1-1000? –

Verwandte Themen