Autor Beitrag
Sirke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 208
Erhaltene Danke: 2



BeitragVerfasst: Mo 07.07.08 16:21 
Hallo zusammen,

Ich möchte einen Byte-Array um eine gewisse Anzahl an Bits erweitern und stehe dabei auf dem Schlauch! Ich verwende für den Byte-Array einen String, da ich damit am besten umgehen kann, lasse mich aber auch gerne überzeugen andere Dateitypen zu verwenden, wenn es damit einfacher gehen sollte ;-)

Also zu dem Problem: Wie schon gesagt möchte ich an eine Folge von Bits weitere Bits dran hängen. Als Beispiel möchte ich immer 7 Bits aneinanderreihen, wobei die sieben Bits auch führende Nullen haben können! Bsp.:
ausblenden Quelltext
1:
2:
3:
1000011 0000111 1100110 0000001
Daraus soll dann sozusagen folgender Byte-Array werden:
10000110 00011111 00110000 00010000


Mit einem Longword bekomme ich das mit Bit-Shifting auch alles hin! In einem Byte-Array dagegen weiß ich nicht, wie ich mit Bitfolgen, die über zwei Bytes oder bei längeren Bitfolgen sogar über mehrere Bytes laufen, machen soll :?

Ich hoffe mein Problem ist verständlich und mir kann der eine oder andere helfen ;-) DANKE!

Grüße, Sirke
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Mo 07.07.08 16:41 
Wenn du keine Hunderte oder Tausende von Bits verwalten willst, nimm doch ein array of Boolean :idea:

Wenn du Delphi ab 4 benutzt, kannst du dynamische Arrays verwenden:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var Bits: array of Boolean;

// Größe setzen
SetLength(Bits, 4);

// Füllen
Bits[0] := True;
Bits[1] := False;
Bits[2] := False;
Bits[3] := True;

// Auslesen
if Bits[2then ShowMessage('Bits[2] = True');

// Größe "nullen", d.h. Speicher wieder freigeben
SetLength(Bits, 0);
Sirke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 208
Erhaltene Danke: 2



BeitragVerfasst: Mo 07.07.08 16:50 
Es geht dabei um (möglichst) redundanzfrei Speicherung von Texten, sodass es schnell mehr als hunderte Bits werden!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 07.07.08 20:14 
Moin!

user profile iconSirke hat folgendes geschrieben:
Es geht dabei um (möglichst) redundanzfrei Speicherung von Texten, sodass es schnell mehr als hunderte Bits werden!
Warum dann nicht einfach bei Bytes bleiben und ein Kompressionsverfahren drüber laufen lassen? :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Sirke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 208
Erhaltene Danke: 2



BeitragVerfasst: Mo 07.07.08 21:48 
Redundanzfrei war dann auch etwas dämlich Formuliert(!): Ich möchte einen Huffman-Code umsetzen! Ja, das ist nicht redundanzfrei, sonder erzeugt an sich unter umständen mehr Redundanz. Ich hatte das nicht gleich erwähnt, weil nicht jeder sofort weiß, was man darunter verseht! Auf jeden Fall geht es dabei ja darum, dass man Symbolen bestimmte Bitfolgen zuweißt und diese wollte ich nun aneinanderreihen.

Mir ging es ja eben um das Problem der Bitfolgen und nicht um die Lösung eines Huffman-Codes oder einem redundanzfreien Text! Da kenne ich genug Komponenten - ich möchte aber selbst knobeln!
Sirke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 208
Erhaltene Danke: 2



BeitragVerfasst: Di 08.07.08 01:11 
Ich habe das nun mit user profile iconNarses Hilfe gelöst bekommen! =) Nicht durch den Post, sondern mit Hilfe seines Binär-Protokolls ;-)

Der Funktion AddBits() übergebe ich den ByteArray und die momentane Länge dieses Arrays in Bits. Dazu noch die Bitfolge und die Länge dieser Bitfolge:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure AddBits( var ByteArray: Stringvar ArrLen: Longword; Bits: Longword; Size: Longword );
begin
  Bits := Bits SHL ( 32 - Size );
  Bits := Bits SHR ( ArrLen MOD 8 );

  Bits := ( (Bits SHR 24AND $FF     ) OR ( (Bits SHR  8AND $FF00     )
       OR ( (Bits SHL  8AND $FF0000 ) OR ( (Bits SHL 24AND $FF000000 );

  SetLength( ByteArray, 1 + ( ArrLen + Size ) div 8 );
  PLongword( @ByteArray[1 + ArrLen div 8] )^ := PLongword( @ByteArray[1 + ArrLen div 8] )^ OR Bits;

  ArrLen := ArrLen + Size;
end;
Die Erklärung dieser Funktion:
  • Zeile 3: Ich schiebe die Bitfolge ans Ende des Longwords, sodass die Bitfolge von Links nach Rechts gelesen am Anfang steht.
  • Zeile 4: Danach schiebe ich die Bitfolge um die Anzahl an Bits nach Links, die bereits in dem letzten Byte gesetzt sind.
  • Die Zeile 3 und 4 kann und wird noch zusammengefasst!
  • Zeile 6 & 7: Die vier Byte Blöcke des Longwords tauschen die Reihenfolge. Grund: Bei der Speicherung über den Pointer (Zeile 10) wird der Longword in umgekehrter Reihenfolge gespeichert.
  • Zeile 9: Neue Länge des ByteArrays.
  • Zeile 10: Das Anfügen der Bitfolge an den String (An dieser Stelle verwende ich den Auszug aus dem Bitär-Protokoll von user profile iconNarses! Vielen Dank! ;-))
Diese Funktion hat leider nur einen Nachteil, den cih noch nicht behoben bekomme: Wenn ich ein Byte genau fülle, dann wird ein weiteres Null-Byte angefügt! Das werde ich auf jeden Fall noch beheben!


Um die Werte aus dem Beispiel aus dem Ersten Post an einen ByteArray zu hängen, muss man folgenden Quelltext schreiben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  AddBits( ByteArray, BitLength, $437 );
  AddBits( ByteArray, BitLength, $077 );
  AddBits( ByteArray, BitLength, $667 );
  AddBits( ByteArray, BitLength, $017 );
Gibt man das ganze nach jedem Schritt als HexDump aus, erhält man folgende Ausagben:
ausblenden Quelltext
1:
2:
3:
4:
86 
86 1C 
86 1F 30 
86 1F 30 10
Das ganze kann man unten auch auf Richtigkeit prüfen (sofern man Bits in Hex umrechnen kann ;-))!


Ich habe das ganze mal so ausführlich gemacht, weil eventuell auch mal andere eine solche Funktion benötigen!

Grüße, Sirke