The book is currently only available in German.
Standard-Bibliothek — `bytes`
Verfügbar — implementiert in Phase B.7.8. Vollständige Spec in
docs/bytes.md.
bytes führt einen eigenen Wert-Typ Bytes für Binär-Daten ein — analog Geld (Kapitel 20) und Zeit (Kapitel 28). Voraussetzung für Binär-Datei-IO, Hashing über Nicht-Text-Daten, Netzwerk-Protokolle.
30.1 Bytes erzeugen
nutze bytes
nimm a = bytes.von_text("Hallo") // UTF-8-Bytes
nimm b = bytes.von_ganzen([0x48, 0x69]) // aus Liste 0-255
nimm c = bytes.aus_hex("4869") // Hex-Decode
nimm d = bytes.aus_base64("SGk=") // Base64-Decode
sag typ(a) // Bytes
sag länge(a) // 5
sag a // bytes(48616c6c6f)
30.2 Immutable — wie Strings
Bytes lässt sich nicht modifizieren. Es gibt kein setze_byte. Wer mutieren will, geht über eine Liste:
nutze bytes
nutze liste
nimm meine_bytes = bytes.von_text("Hallo")
nimm roh = bytes.als_ganze(meine_bytes) // Bytes → liste<ganz>
nimm geändert = liste.eingefügt(roh, 0, 255) // 255 vorne einfügen
nimm ergebnis = bytes.von_ganzen(geändert) // zurück zu Bytes
sag ergebnis // bytes(ff48616c6c6f) — 255 (ff) ist jetzt das erste Byte
Beachte die Variablennamen: nenn die Liste nicht
liste(das verdeckt dasliste-Modul, dann scheitertliste.eingefügt) und nutze nichtneuals Variablennamen (neuist reserviert).
Begründung: keine Aliasing-Bugs, klares Ownership — gleiche Linie wie text (siehe Kapitel 19).
30.3 Konversion
nimm b = bytes.von_text("Hi")
sag bytes.als_text(b) // "Hi"
sag bytes.als_ganze(b) // [72, 105]
sag bytes.als_hex(b) // "4869"
sag bytes.als_base64(b) // "SGk="
bytes.als_text wirft bei nicht-UTF-8-Bytes einen Fehler. Wer einen Default haben will:
sag bytes.als_text_oder(böse_bytes, "(unlesbar)") // gibt "(unlesbar)" zurück
30.4 Operationen
nimm hw = bytes.von_text("Hallo Welt")
sag bytes.byte_bei(hw, 0) // 72 (= 'H')
sag bytes.byte_bei(hw, -1) // 116 (letztes Byte)
sag bytes.als_text(bytes.scheibe(hw, 6, 10)) // "Welt"
sag bytes.enthält(hw, bytes.von_text("Welt")) // wahr
sag bytes.ist_gleich(hw, hw) // wahr
nimm zusammen = bytes.verkettet(
bytes.von_text("foo"),
bytes.von_text("bar")
)
sag bytes.als_text(zusammen) // "foobar"
30.5 Praxis: Magic-Bytes erkennen
Viele Datei-Formate beginnen mit charakteristischen Magic-Bytes. Mit bytes.enthält lassen sich diese prüfen:
nutze bytes
nutze datei
nimm png_magic = bytes.aus_hex("89504e470d0a1a0a")
nimm rohdaten = datei.bytes_inhalt("./bild.png") // setzt eine vorhandene Datei voraus
wenn bytes.enthält(rohdaten, png_magic) {
sag "Das ist eine PNG-Datei"
}
30.6 Datei-IO mit Bytes
Für Binär-Dateien (Bilder, ZIPs, Audio, …) gibt's seit Phase B.7.8 zwei neue datei-Funktionen:
| Funktion | Zweck |
|---|---|
datei.bytes_inhalt(p) |
Datei als rohe Bytes lesen (keine UTF-8-Validierung) |
datei.schreibe_bytes(p, b) |
Bytes direkt in Datei schreiben |
// Datei kopieren — funktioniert für jeden Datei-Typ:
nimm rohdaten = datei.bytes_inhalt("quelle.bin")
datei.schreibe_bytes("ziel.bin", rohdaten)
datei.inhalt und datei.schreibe (text-Form mit UTF-8-Validierung) bleiben unverändert für reine Text-Dateien.
30.7 Roundtrips funktionieren immer
nimm orig = bytes.von_text("Roundtrip-Test mit Umlauten: äöüß")
// hex → bytes:
nimm via_hex = bytes.aus_hex(bytes.als_hex(orig))
sag bytes.ist_gleich(orig, via_hex) // wahr
// base64 → bytes:
nimm via_b64 = bytes.aus_base64(bytes.als_base64(orig))
sag bytes.ist_gleich(orig, via_b64) // wahr
// liste<ganz> → bytes:
nimm via_liste = bytes.von_ganzen(bytes.als_ganze(orig))
sag bytes.ist_gleich(orig, via_liste) // wahr
30.8 Was nicht in bytes v1 ist
- Operator-Wiring (
b[i],b1 + b2,b1 == b2) — die Funktionenbyte_bei/verkettet/ist_gleichreichen. Operatoren können später additiv kommen. - Mutations-Funktionen — bewusst nicht (siehe §30.2).
prozess.ausgeführt_bytesundhash.sha256_bytes— Folge-Patches in späterer Phase.- Streaming-Bytes für riesige Dateien — eigene Phase mit io-Reader-Pattern.
- URL-safe-Base64, Endian-Funktionen (
als_ganz_le/_be) — selten gebraucht, wenn Bedarf später.