Der Raumflug

Übersicht Sonstiges Smalltalk

Neue Antwort erstellen

BladeRunner

Moderator

Betreff: Der Raumflug

BeitragMo, Feb 10, 2014 0:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine kleine Sonde wird in ein benachbartes Sternensystem entsandt. Grundlage ist ein neuartiger Antrieb der nahezu Lichtgeschwindigkeit verspricht.

Die Sonde sendet regelmäßig Statusmeldungen zur Erde. Durch die wachsende Entfernung werden jedoch zunehmend Übertragungsfehler vorkommen, weshalb die Sonde jede Nachricht mehrfach versendet um am Ende die Daten möglichst fehlerfrei übertragen zu haben.

Hier kommt ihr nun ins Spiel:
Schreibt zwei Funktionen:
- Die erste nimmt eine Nachricht entgegen, dupliziert sie n-mal und verrauscht dann m% der Zeichen mit einem Zufallswert. Auch die Position der verrauschten Zeichen ist zufällig, d.h. es kann auch geschehen dass ein Zeichen mehrfach verrauscht. Dies simuliert was mit der Nachricht passiert wenn sie die Weiten des Alls passiert.
Aufruf der Funktion : Encode(message:string, times:int, disturbance:int)

-die Zweite nimmt den Verrauschten Text entgegen und versucht eine möglichst Valide Version der Ursprungsnachricht zu erstellen. Es ist nur bekannt wie oft der Ursprungstext gesendet wurde.

Aufruf der Funktion: Decode:String(message:string, times:int)


Entschlüsselt folgende Nachricht (25 Wiederholungen):
Zitat:
YP are no" }lo—ë!ÄAll£o y
Ù· bXseÐaÔei=eá<ng –« øsÇ°±l; done,QEa}thlBZ–!Mu areNn‹tflne— ø7l ofoour MReÑarŠÃbûož Po uÄÉ ÂÓydo,ú­Ht*ïikg!mo2 aÕe notMalBÅe!ØAl2ÒÀ“ 4åu ÿws  QîeTb,lêQgto ˆÂ%c:el èd1n¶ ‚a*âhˆià!¾—n are no% (ho¯ú! õÌl f yoÈØPûaé0®are fel>ngÍt[ Xs. ]e÷lDE?nì¢ âaûth3-“4ÐYPu=qe nå– ALÀne!2AlldnŽ Gour D»pe£arÙ ¦e5oO^ Ëõ€us. WeÆl >«23ua<vhl QT!ŒÕ¾’Œre no ÖlõÚ ülS™oR©©ouì´ârse rTZelonl–Ùo0us.;ellÍone,©ùŒrtP$n¤&÷^ are›n¿> aponF1}All o& Œu!×ÂFn r0ReCong Ai us. WÇ®¬d^ne, Earthli)g!Y|Ѫ+r¡‘ötYa
Rne!'Al ofÉyo-r bas™Y²e ýÂlong 8o s. W0Þo§d}K,<E(ÈtÎlRÖ"»o6† ø âQt L÷oãeI-Ãll oì׶oòr ßase arîUbt¸ng to Žs. WRll –on„Ó Eÿrt‚§ÈnÔ!S0 ðCeknFŽha&necsAllto¡uyocr6basey5rœ bNlo/g t< us.sW¹|l³d?nï8 Eaóphli%gYêu a5w I犩alo¥¤Ü A.{°f yj6r ba*B re C¤loþgœto u %DWÁÿ4д¼e´NEar¦hlig!Y#u)Áre"not ¤loŸe!Qlë oB¿y!urbas& rî belnFt$þs.éWelÄqdo˜Ø, EÆrtl³BÊì>*uŒ¥rÇ otma_oöeÍzmlæ‚ofGÂoÅ fbtÖe a|• el×Û+rtÕçwsÓ W}_Õd¤n‹ÙîEartůn[!Y¸­ 3Ÿe notóYlMÓe! AÝïof your€base are bâï¸õgŸmo u. W4ll·ÑoàZ€ Ea 4li~i£6ou arS no­ša*oA
!ÑA•MÕf yÔu²çÚ®´e—a5Q+belon` tú uÖ.YWelŠ÷on b Sarthi·g!You 5ëeëꏸ‹”lö?e! A8lHbfÒyouÌŒ”.sª`ar¿bemÓÎ& tÕ uÐ aWlF 0±n|Ó E´rt\Ú…nç!!ou ar EoÅ«lonQz AlØ ofy»r ™@sFÝare
ÿe`onß to R. ŒEll )o©eZ[E¦âhn\œnˆYˆ« ìre Àø“ íÝon¦YÉlà of §RuðœGaµÂaÁ1beloÏg¨Ôoãs. ½ellÒyo:Ó,;^Òr0û^nK!Mou €‡v noŸ al\H&E Alï mÑ—O^›¦se$a3 m(getÌ Äs Well dX#d,Φatøóÿ9Ü>)o ar noH~9™Kne! AllƒofŒyoµ base a¶YСeÆ#n‡ 1íus. WlZ don=½ ËaŸthÅ\n–nYmùZÎX…’UC°aŽoB[!lrl¸nØf yXÁr baáe ³re belongþì“ l#YÃWT=íèdΏ=,W
}r¸hliJg!Yo¾ afï˜n˜tˆalon®! Almof your (ksy afeŽeloŽª óo us “ iï o„w, Earëh –€g:Y2N†»ŽenStÛlone A+l oTG2ourÍùaeô¶ce bçeÚfgPto ®s> WtlÄÍdonÌ, öaïtÝl‹ág!²ouaar&­ t O¯one!”A-KoYÆ,]ˆÉbas a2/ÅlG~g th*u».È
eT doe —¹rthlhng!UÊ›8areŒnÿt alˆneÇ ll  su@øeas~q[[eblo/gt\ uEj ÿ<l@ d}neâäa9thúˆ8n

Viel Erfolg.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Lobby

BeitragMo, Feb 10, 2014 1:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hört sich interessant an. Was genau verstehst du unter verrauscht? Und ist es möglich, dass infolge dessen deine Code nicht ganz eindeutig ist, weil etwa bestimmte ASCII-Steuerzeichen fehlen? Das ist nur eine Frage, um Fehler in diese Richtung von vornherein auszuschließen Razz .
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

BladeRunner

Moderator

BeitragMo, Feb 10, 2014 1:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Verrauscht bedeutet dass ein Byte durch ein zufälliges anderes ausgestuascht wird. Mit allen Konsequenzen.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

SpionAtom

Betreff: Ich muss auch nochmal blöd fragen

BeitragMo, Feb 10, 2014 9:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Liegt es an der Windowszeicheninterpretation, dass ich keine 25 * X Zeichen habe?
Denn laut Aufgabenstellung werden ja keine Zeichen verschluckt, sondern bloß verändert.

Oder habe ich einen Denkfehler Question
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080

Lobby

BeitragMo, Feb 10, 2014 11:08
Antworten mit Zitat
Benutzer-Profile anzeigen
In diese Richtung zielte meine Frage auch ab. Ist es also gewollt, dass du uns keine Datei zum Herunterladen angibst?

Wie ist das Ganze eigentlich gedacht, so als Art Miniwettbewerb wo man hier seine Ideen und Umsetzung schreiben kann, oder steckt mehr dahinter?
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

DAK

BeitragMo, Feb 10, 2014 13:00
Antworten mit Zitat
Benutzer-Profile anzeigen
@Verrauscht: Auf welcher Encodierung basiert das und worauf wird da verrauscht? Ist das z.B. in ASCII und du verrauscht über alle 256 möglichen Zeichen, dann werden einige Zeichen durch undruckbare Zeichen ersetzt (alle Zeichen unter 0x21 und alle über 0x7E).
Verwendest du eine andere Codierung als ASCII (was ich Aufgrund der vielen komischen Sonderzeichen vermute) wird es überhaupt lustig. Da kann man nur mehr raten, vor allem weil z.B. UTF-8 ist ein Zeichen zwischen 1 und 4 Byte lang. Da kann man auch nichts mehr rausraten.

Ich finde die Idee des Ganzen sehr interessant, denke aber, dass es um einiges besser wäre, wenn du festlegst, dass die Nachricht in ASCII gegeben ist, und die Zeichen dann entweder nur zwischen 0x21 (=33) und 0x7E (=126) variiert werden (also nur druckbare Zeichen in Standard-ASCII) oder in einer Formatierung mit fixer Zeichenlänge (z.B. 1 Byte pro Zeichen, oder UTF-16, wo die Länge 2 Byte pro Zeichen beträgt) und danach das Ergebnis in Base64 encodieren, damit keine Daten beim Kopieren ins/aus dem Forum verloren gehen.
Gewinner der 6. und der 68. BlitzCodeCompo

Starwar

BeitragMo, Feb 10, 2014 14:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Oder du gibst uns das ganze als HEX-Dump und nennst uns die Zielcodierung. Dann können wir beliebige Bitfehler annehmen.

(Wenn der Text oben Steuerzeichen enthält kann es ja sein, dass sie garnichts gedruckt worden sind und so beim Kopieren verloren gegangen sind)

MFG

PSY

BeitragMo, Feb 10, 2014 17:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Earthling.
All of your base are belong to us.

Soviel kann ich ohne coden rauslesen Wink
PSY LABS Games
Coders don't die, they just gosub without return

BladeRunner

Moderator

BeitragMo, Feb 10, 2014 21:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm, da ist beim pasten wohl murks passiert.
Ich werde wenn ich wieder zuhause bin einen HexDump erstellen (der anders sein kann, das Rauschen ist ja zufällig) und online stellen.
Das wird aber bis mindestens morgen mittag dauern.
Sorry für den Fehler.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

ZEVS

BeitragMo, Feb 10, 2014 21:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Und ich dachte, die Rekonstruktion gehört mit dazu: Code: [AUSKLAPPEN]
59 8F 50 20 61 72 65 20 6E 6F 22 20 7D 6C 6F 97 EB 21 C4 41 6C 6C A3 6F 12 20 79 0A D9 B7 20 62 58 73 65 D0 61 D4 65 69 3D 65 E1 3C 6E 67 20 96 AB 20 F8 73 17 C7 B0 B1 6C 3B 20 64 6F 6E 65 2C 51 45 61 7D 74 68 6C 42 5A 96 21 4D 90 75 20 61 72 65 4E 6E 8B 74 9D 66 6C 0F 6E 65 97 20 F8 37 6C 20 6F 66 01 6F 6F 75 72 20 4D 52 8F 65 D1 61 72 8A C3 62 01 FB 6F 9E 05 20 50 6F 20 75 C4 C9 20 C2 D3 79 8D 64 13 6F 12 06 2C 10 FA AD 48 74 2A EF 69 6B 67 21 6D 6F 32 20 61 D5 65 20 6E 6F 74 4D 61 6C 42 C5 65 21 D8 41 6C 32 D2 C0 93 20 34 E5 75 0F 20 FF 77 73 A0 20 51 EE 65 54 62 2C 6C EA 51 67 13 74 6F 20 88 C2 25 63 3A 65 6C 0B E8 64 31 6E 11 B6 20 82 61 2A E2 68 88 69 E0 14 21 BE 97 6E 20 61 72 65 20 6E 6F 25 20 28 68 6F AF FA 21 20 F5 CC 6C 20 20 66 20 79 6F C8 D8 50 FB 61 E9 30 AE 61 72 65 20 66 65 6C 3E 6E 67 CD 74 5B 20 58 73 2E 20 5D 65 F7 6C 44 45 3F 6E EC A2 20 E2 61 FB 74 68 33 2D 93 34 D0 59 50 75 1E 3D 71 65 20 6E E5 96 20 41 4C C0 6E 65 21 32 41 6C 6C 64 6E 8E 20 47 6F 75 72 20 44 BB 70 65 A3 61 72 D9 20 A6 65 35 6F 4F 5E 20 CB F5 80 75 73 2E 20 57 65 C6 6C 20 3E AB 1F 32 33 75 7F 61 3C 76 68 6C 0C 51 54 21 8C D5 BE 92 8C 72 65 20 6E 6F 20 20 D6 6C F5 DA 04 06 20 FC 6C 53 99 6F 52 A9 A9 6F 75 EC B4 E2 72 73 65 20 0B 72 1F 54 5A 65 6C 6F 6E 6C 96 D9 6F 30 75 73 2E 3B 1F 65 6C 6C CD 1D 6F 6E 65 2C A9 F9 8C 72 74 50 24 04 6E A4 7F 26 F7 5E 20 61 72 65 9B 6E BF 3E 20 61 70 6F 6E 46 31 7D 41 6C 6C 20 6F 26 20 16 8C 75 21 D7 C2 1B 46 6E 20 19 72 30 52 16 65 43 6F 6E 67 20 41 69 20 75 73 2E 09 57 C7 AE AC 18 64 5E 6E 65 2C 20 45 61 72 74 68 6C 69 29 67 21 59 7C D1 AA 2B 72 A1 91 F6 02 74 59 61 0A 52 6E 65 21 27 41 6C 1E 20 6F 66 C9 79 6F 2D 72 20 62 61 73 81 99 59 B2 65 20 FD C2 6C 6F 6E 67 20 38 6F 20 01 73 2E 20 57 30 DE 6F A7 64 7D 16 4B 2C 3C 45 28 C8 74 CE 6C 52 D6 22 19 BB 6F 02 36 86 0C F8 20 E2 51 74 20 4C F7 6F E3 65 49 2D C3 6C 6C 20 6F EC D7 B6 6F F2 72 20 DF 61 73 65 20 61 72 EE 55 62 74 B8 81 6E 67 20 74 6F 20 8E 73 2E 20 57 52 6C 6C 20 96 6F 6E 84 D3 20 45 FF 72 74 82 A7 C8 6E D4 21 11 53 30 20 F0 43 65 6B 6E 46 8E 68 61 0E 26 6E 65 63 73 41 6C 6C 74 6F A1 75 79 6F 63 72 36 62 61 73 65 79 35 72 9C 20 62 4E 6C 6F 2F 67 20 74 3C 20 75 73 2E 73 57 B9 7C 6C B3 64 3F 6E EF 38 20 45 61 F3 70 68 6C 69 25 67 03 59 EA 75 20 61 35 77 20 49 E7 8A A9 61 6C 6F A5 A4 DC 20 41 2E 7B B0 07 66 20 79 6A 36 72 20 62 61 2A 42 20 13 72 65 20 43 A4 6C 6F FE 67 9C 74 6F 20 75 0C 25 44 57 C1 FF 34 D0 04 B4 BC 65 B4 4E 45 61 72 A6 68 6C 69 17 67 21 59 23 75 29 C1 72 65 22 6E 6F 74 20 A4 6C 6F 9F 65 21 9D 51 6C EB 20 6F 42 BF 79 21 75 72 7F 62 61 73 26 20 14 72 EE 20 62 65 6C 07 6E 06 46 74 24 18 FE 73 2E E9 57 65 6C C4 71 64 6F 98 D8 2C 20 45 C6 72 74 07 6C B3 42 CA EC 3E 2A 75 8C A5 72 C7 20 0E 6F 74 6D 61 5F 6F F6 65 CD 7A 6D 6C E6 82 6F 66 47 C2 6F C5 09 66 62 74 D6 65 20 61 7C 95 20 9D 65 6C D7 DB 2B 72 74 D5 E7 77 73 D3 20 57 7D 5F 18 D5 64 A4 6E 8B D9 EE 45 61 72 74 C5 AF 1D 6E 5B 21 59 B8 AD 20 33 9F 65 20 6E 6F 74 F3 59 6C 4D D3 65 21 20 41 81 DD EF 6F 66 20 79 6F 75 72 80 62 61 73 65 0C 61 72 65 20 62 E2 EF B8 F5 67 9F 6D 6F 20 75 1F 2E 20 57 34 6C 6C B7 D1 6F E0 5A 80 20 45 61 20 1E 34 6C 69 7E 69 A3 36 6F 75 20 61 72 53 20 6E 6F AD 9A 61 2A 6F 41 0A 21 D1 41 95 4D D5 05 66 20 79 D4 75 B2 E7 DA AE B4 65 97 61 35 51 2B 62 65 6C 6F 6E 60 20 74 FA 20 75 D6 2E 59 57 65 6C 03 8A F7 6F 6E 0B 62 20 53 61 72 74 68 81 69 B7 67 21 59 6F 75 20 35 EB 65 EB EA 8F B8 8B 94 6C F6 3F 65 21 20 41 38 6C 48 62 66 D2 79 6F 75 CC 8C 94 2E 73 AA 60 61 72 17 BF 62 65 6D D3 CE 26 20 74 D5 20 75 D0 0C 61 57 18 6C 46 20 30 B1 6E 7C D3 20 45 B4 72 74 5C DA 85 6E E7 21 21 6F 75 20 61 72 7F 20 45 6F C5 AB 03 6C 6F 6E 51 7A 20 41 6C D8 20 6F 66 1E 79 1A BB 72 20 99 40 73 46 DD 61 72 65 0A FF 65 60 6F 6E DF 20 74 6F 20 1F 52 2E 20 8C 45 6C 6C 20 29 6F A9 65 5A 5B 45 01 A6 E2 68 6E 5C 9C 6E 88 59 88 AB 20 EC 72 65 20 C0 F8 93 20 ED DD 6F 6E A6 1A 59 C9 6C C3 20 6F 66 20 A7 52 75 F0 9C 47 61 B5 07 C2 61 15 C1 31 62 65 6C 6F CF 67 A8 D4 6F 9D E3 73 2E 20 BD 65 6C 6C D2 79 6F 3A D3 2C 3B 5E D2 72 30 06 FB 5E 6E 4B 21 4D 6F 75 20 80 87 76 20 6E 6F 9F 20 61 6C 5C 48 26 45 20 41 6C EF 20 11 6D 05 D1 0F 97 4F 5E 9B A6 73 65 24 61 33 06 20 04 6D 28 81 14 67 65 74 CC 20 C4 73 0E 09 57 65 6C 6C 20 64 58 23 64 2C CE A6 61 14 74 F8 F3 FF 39 DC 3E 29 6F 07 20 61 72 1E 20 6E 6F 48 7E 39 99 4B 6E 65 21 20 41 6C 6C 83 6F 66 8C 79 6F B5 81 20 62 61 73 65 20 61 B6 59 D0 A1 65 C6 23 6E 87 20 07 31 ED 75 73 2E 20 57 1E 6C 5A 20 64 6F 6E 3D BD 20 CB 61 9F 74 68 C5 5C 6E 96 6E 59 6D F9 5A 15 CE 58 85 92 55 43 B0 61 8E 6F 42 5B 21 6C 72 6C B8 6E D8 66 20 79 58 C1 72 20 62 61 E1 65 20 B3 72 65 20 62 65 6C 6F 6E 67 FE EC 93 20 6C 23 59 C3 57 54 3D ED E8 64 CE 8F 3D 2C 57 0A 7D 72 B8 68 6C 69 4A 67 21 59 6F BE 20 61 66 EF 98 6E 98 74 88 61 6C 6F 6E AE 21 20 41 6C 11 6D 6F 66 20 79 6F 75 72 20 28 6B 73 79 20 61 66 65 8E 1C 65 6C 6F 8E AA 20 F3 6F 20 75 73 11 20 93 20 69 EF 20 8F 6F 84 77 2C 20 45 61 72 EB 68 A0 96 80 67 3A 59 32 4E 86 BB 8E 65 1B 6E 53 74 16 DB 6C 6F 6E 65 1E 20 41 2B 6C 20 6F 54 47 32 6F 75 72 CD F9 61 13 65 F4 B6 63 65 20 62 E7 65 DA 66 67 50 74 6F 20 AE 73 3E 20 57 74 6C C4 CD 64 6F 6E CC 2C 20 F6 61 EF 74 DD 6C 8B E1 67 21 B2 6F 75 61 61 72 81 26 AD 09 74 20 4F AF 6F 6E 65 21 94 41 19 2D 4B 6F 1B 59 C6 2C 5D 88 C9 62 61 73 7F 20 61 07 06 32 2F C5 6C 47 7E 67 20 74 68 2A 75 BB 2E C8 0A 65 1E 54 20 64 6F 1C 65 8D 20 97 B9 72 74 68 6C 68 6E 67 21 55 CA 9B 38 61 72 65 8C 6E FF 74 20 61 6C 88 6E 65 C7 20 8D 6C 6C 20 1E 11 20 73 19 75 40 F8 65 61 73 7E 71 5B 5B 65 9D 62 1B 6C 6F 2F 67 18 74 5C 20 75 45 6A 20 FF 3C 6C 40 20 64 7D 6E 65 E2 E4 15 61 39 74 68 FA 16 88 38 6E


edit: Damit geht es recht einfach. BlitzMax: [AUSKLAPPEN]
SuperStrict
Const frequency:Int = 25, file$ = "encoded.bin"
Local bank:TBank = LoadBank(file)
Local length:Int = bank.Size()/frequency
Local freq:Int[256,length]
For Local i:Int = 0 Until frequency
Local offset:Int = i*length
For Local j:Int = 0 Until length

freq[PeekByte(bank,offset+j),j] :+ 1

Next
Next

Local str$
For Local i:Int = 0 Until length

Local maxl:Int = 0, maxf:Int = freq[0,i]
For Local l:Int = 1 Until 256

Local f:Int = freq[l,i]
If f >= maxf Then

maxl = l
maxf = f

EndIf

Next
str :+ Chr(maxl)

Next
Print str

Um den Buchstaben der Position i des Originaltextes zu bestimmen, wähle ich hier einfach den häufigsten Buchstaben an dieser Stelle in den verrauschen Wiederholungen aus. Bei stärkerer Verzerrung könnte es dazu kommen, dass etwas falsches an Häufigkeit überwiegt. Das ist hier nicht so, deshalb sind kompliziertere Methoden mit bedingten Wahrscheinlichkeiten (Welcher Buchstabe ist, bei den gegebenen Häufigkeiten unter Betrachtung von absoluter Häufigkeit und Kontext der wahrscheinlichste?) nicht nötig. Das Ergebnis:

You are not alone! All of your base are belong to us. Well done, Earthling!

Die erste Aufgabe ist nicht weiter schwierig:
BlitzMax: [AUSKLAPPEN]
SuperStrict
SeedRnd MilliSecs()
Function Encode$(message$, times:Int, disturbance:Int)

Local result$
While times > 0

times :- 1
Local msg$ = message

For Local i:Int = 0 Until disturbance

Local index:Int = Rand(0, msg.length-1)
msg = msg[..index] + Chr(Rand(0, 255)) + msg[index+1..]

Next

result :+ msg

Wend
Return result

End Function
Print Encode("Hello", 3, 2)

BladeRunner

Moderator

BeitragDi, Feb 11, 2014 4:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schöne Lösung Smile
Wer noch ein wenig experimentieren möchte, folgende Vorschläge:

- es ist nicht bekannt wie oft die Nachricht gesendet wurde. Ermittelt anhand des Streams die wahrscheinlichste Lösung.

- Die Sonde hat immer nur recht kurze Zeitfenster zum Senden der Nachrichten. Schreibt eine simple Kompression um die Nachricht einzukürzen. Der Dechiffrierer muss diese auch anwenden können.
(Vorschlag: Es wird nur Text/Ziffern/Satzzeichen übertragen, daher sollten weniger Bits pro Zeichen ausreichend sein)
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

DAK

BeitragDi, Feb 11, 2014 20:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab jetzt mal was in Java dazu gebastelt. Ist relativ quick-and-dirty, also erwartet mal nicht zu viel von dem Code.

Was das hier tut: Zuerst wird das Ganze mit Huffman kodiert und in Blöcke zerteilt (Größe ist frei definierbar, das heißt, ein Block ist meistens nicht ein Zeichen lang). Jeder Block bekommt ein oder mehrere Parity-Bits (je nach Setting) und die Nachricht ist fertig zum Übertragen. Beim Empfang wird dann jeder Block bitweise abgetastet. Beschädigte Blocks (erkennbar anhand des fehlgeschlagenen Parity-Checks) werden zuerst ignoriert, und nur wenn es keinen einzigen validen Block in allen Wiederholungen gibt, wird das Bit gewählt, was in den meisten Blocks vorkommt.


Die Huffman-Kodierung ist eine Komprimierung, bei der jedem Buchstabe durch eine eindeutige Binär-Kodierung ersetzt wird. Um auf diese Kodierungen zu kommen muss man den Huffman-Lern-Algo mit einem (möglichst langen) Beispieltext füttern, aus der er sich die Häufigkeit für jeden Buchstaben ausrechnet. Buchstaben, die häufiger vorkommen bekommen dann einen kürzeren Binärwert (wie z.B. das Leerzeichen in meinem Fall, dass den Wert 101 hat), seltenere Buchstaben bekommen einen längeren Binärwert (bei mir ist dafür Q ein gutes Beispiel, das den Wert 11001010011101 hat.
Dadurch, dass häufigere Buchstaben somit weniger Speicher verbrauchen, wird der Eingabetext statistisch gesehen kürzer.
Um es authentisch zu halten habe ich als Beispieltext ein Transkript von der Apollo 11-Mondlandung (minus den Sachen in Klammern, da die ja nicht gefunkt wurden) genommen.

Nimmt man den Beispielsatz der in dieser Aufgabe gestellt wurde und Huffman-codiert ihn ist das Ergebnis 368 Bit lang.
Wird der Satz mit 7-Bit ASCII kodiert, dann ist er 525 Bit lang. Bei 8-Bit ASCII wären es 600 Bit und bei UTF-16 wären es sogar 1200 Bit. Wie man sieht bringt Huffman da schon ein Bisschen.

Huffman hat aber ein Problem: durch die nicht-fixe Bitlänge der Buchstaben kann ein 1-Bit-Fehler alle nachfolgenden Buchstaben korrumpieren. Wird nämlich durch den Bit-Fehler z.B. nicht ein 4-Bit-Buchstabe sondern ein 6-Bit-Buchstabe gewählt, sind alle nachfolgenden Buchstaben um 2 Bit verschoben, was zu komplett anderen Ergebnissen führt. Das heißt, der gewonnene Platz kommt auf Kosten von weniger Übertragungssicherheit.


Wir haben hier einiges an Platz eingespart, aber bei einer Übertragung durch den Weltraum ist Übertragungssicherheit absolut wichtig. Da sich alle Deep-Space-Satelliten den Funk teilen müssen (immer einer nach dem anderen ist dabei dran) ist ein ungeplantes Nochmal-Senden-Müssen ziemlich ungut, da das heißt, dass alle anderen Satelliten noch länger auf Sendezeit warten müssen.
Deswegen ist es hier besser von Anfang an fix ein bisschen mehr zu brauchen, aber dafür berechenbar viel Zeit zu brauchen.

Deswegen habe ich die durch die Huffman-Codierung frei gewordenen Bits für einen Parity-Check verwendet. Da wir bei unserer Störungsart keine Zahlendreher vorkommen genügt hier ein einfacherer Parity-Check und man braucht keine Gewichtungen, wie z.B. bei der EAN.
Das Ganze schaut so aus:
-Zuerst wird der Input in Blöcke unterteilt. Jeder dieser Blöcke hat k bit Länge.
-Für jeden k-Bit-Block wird die Ziffernsumme errechnet.
-Diese Ziffernsumme wird auf m-Bit länge gestutzt (mittels Modulo) und hinten an den Block angehängt.

Ein so gesicherter Block hat also k+m Bit Länge. k Bit Nutzdaten und m Bit Prüfsumme. Damit können bis zu 2^m Bitfehler erkannt werden.

Beim Auslesen wird dann zuerst jeder Block hergenommen und in Nutzdaten und Prüfsumme zerlegt. Es wird dann aus den Nutzdaten eine neue Prüfsumme errechnet und verglichen, ob die errechnete Prüfsumme sowie die mitgeschickte Prüfsumme mit einander übereinstimmen. Stimmen sie, dann gilt der Block als unverfälscht. Er kann aber noch immer falsch sein, wenn es mehr Fehler gegeben hat als mit der Prüfsumme überprüft werden kann.
Als Beispiel: Nutzdaten sind 011, und für die Prüfsumme ist 1 Bit lang. Das bedeutet, dass die Prüfsumme sich aus der Ziffernsumme Modulo 2 ergibt, also 0 ist. Der ganze Block ist also 0110. Gibt es einen Fehler, dann ist die Prüfsumme falsch: 0010 würde z.B. eine Prüfsumme von 1 benötigen, hat aber 0 ist also falsch.
Gibt es jetzt aber zwei Fehler, dann funktioniert das aber nicht mehr: 1010 wird als gültig durchgewinkt.

Die Prüfsummen werden dann entfernt und die Nutzdaten aus allen Blöcken werden dann aneinander gereiht.
Das wird dann noch mit Huffman dekodiert und fertig.

Das Ganze ist überraschend stabil. Ich habe probiert, die Länge der codierten Strings plus Prüfsummen kleiner zu halten als 7-Bit-ASCII-codierten String. Das heißt, bei unserem Testfall muss der Huffman-codierte String mit Prüfsummen kürzer sein als 525 bit.

Ich habe hier deswegen Blöcke mit 12 Bit Nutzdaten und 4 Bit Prüfsumme genommen, womit der String auf 492 Bit Gesamtlänge kommt was immer noch kürzer ist als 7-Bit-ASCII. Diese Größen für Nutzdaten und Prüfsumme sind ganz sinnvoll so, da 4 Bit Prüfsummen bis zu 16 Fehler erkennen können, und Blocks mit einer Gesamtlänge von 16 Bit maximal 16 Fehler haben können. Fehler werden also in beinahe jedem Fall erkannt.
Die einzige übrige Fehlerquelle ist, wenn ein Block in jeder Einzelnen der 25 Wiederholungen nicht richtig übertragen wurde. Dann wird aus diesem Block in jeder Übertragung geschaut, ob 0 oder 1 häufiger vorkommt und das dann genommen. Hierbei kann die Prüfsumme nichts mehr beitragen.

Das Ganze rennt ziemlich stabil. Bei 12 Bit Nutzdaten, 4 Bit Prüfsumme und 25 Wiederholungen bekommt man selbst bei 85% Fehlerrate noch meistens ein fehlerloses Ergebnis. Dreht man das Verhältnis rauf auf 10 Bit Nutzdaten und 10 Bit Prüfsumme, dann gehen sich auch 95% Fehlerrate aus.

Und wenn die Übertragung daneben geht, dann kriegt man die gleichen lustigen blockbasierten Fehler die man aus den ganzen schlechten Sci-Fi-Spielen gewohnt ist Wink

Code: [AUSKLAPPEN]
import java.util.HashMap;

/**
 *
 * @author Dakkaron
 */
public class SpaceCommunication {
    public final static int REPETITIONS = 25;
    public final static double ERRORCHANCE=.85;
    public final static int BITPERPARITY=12;
    public final static int PARITYLENGTH=4;
    public final static boolean USEPARITY=true;
    public final static String ORIGINAL_TEXT="You are not alone! All of your base are belong to us. Well done, Earthling!";
   
    HashMap<String,String> huffmanEncodeMap;
    HashMap<String,String> huffmanDecodeMap;
   
    public static void main(String[] args) {
       
        SpaceCommunication temp = new SpaceCommunication();
        temp.initHuffman();
       
        System.out.println("Length of the unencoded string: "+ORIGINAL_TEXT.length()*7+" bit");
        System.out.print("Encoding... ");
        long ms = System.currentTimeMillis();
        String huffmanEncoded = temp.huffmanEncode(ORIGINAL_TEXT);
        System.out.println((System.currentTimeMillis()-ms)+"ms");
        System.out.println("Length of the encoded string: "+huffmanEncoded.length()+" bit");
       
        String huffmanEncodedP;
        if (USEPARITY) {
            System.out.print("Adding Parity Bits... ");
            ms = System.currentTimeMillis();
            huffmanEncodedP = temp.addParity(huffmanEncoded, BITPERPARITY, PARITYLENGTH);
            System.out.println((System.currentTimeMillis()-ms)+"ms");
            System.out.println("Length of the encoded string: "+huffmanEncodedP.length()+" bit");
        } else {
            huffmanEncodedP = huffmanEncoded;
        }
       
        System.out.print("Copying... ");
        ms = System.currentTimeMillis();
        String huffmanEncodedMultiplied = temp.copyMultipleTimes(huffmanEncodedP, REPETITIONS);
        System.out.println((System.currentTimeMillis()-ms)+"ms");
       
        System.out.print("Adding errors... ");
        ms = System.currentTimeMillis();
        String huffmanEncodedMultipliedErrors = temp.addErrors(huffmanEncodedMultiplied, ERRORCHANCE);
        System.out.println((System.currentTimeMillis()-ms)+"ms");
       
        System.out.print("Removing errors... ");
        ms = System.currentTimeMillis();
        String huffmanEncodedErrorsRemoved;
        if (USEPARITY) {
            huffmanEncodedErrorsRemoved = temp.removeErrorsUsingParityCheck(huffmanEncodedMultipliedErrors, REPETITIONS, BITPERPARITY,PARITYLENGTH);
        } else {
            huffmanEncodedErrorsRemoved = temp.removeErrors(huffmanEncodedMultipliedErrors, REPETITIONS);
        }
        System.out.println((System.currentTimeMillis()-ms)+"ms");
       
        System.out.print("Decoding... ");
        ms = System.currentTimeMillis();
        String decodedText = temp.huffmanDecode(huffmanEncodedErrorsRemoved);
        System.out.println((System.currentTimeMillis()-ms)+"ms");
       
        System.out.println(ORIGINAL_TEXT);
        System.out.println(decodedText);
    }
   
    public String addParity(String in,int bitPerParity,int parityLength) {
        if (bitPerParity<1) {
            throw new IllegalArgumentException("bitPerParity must be higher than 0");
        }
        if (parityLength<1) {
            throw new IllegalArgumentException("parityLength must be higher than 0");
        }
        StringBuilder outStringBuilder = new StringBuilder();
        for (int i=0;i<Math.ceil((double)in.length()/bitPerParity);i++) {
            String block;
            if ((i+1)*(bitPerParity)<in.length()) {
                block = in.substring(i*(bitPerParity),(i+1)*(bitPerParity));
            } else {
                block = in.substring(i*(bitPerParity));
            }
            int parity=0;
            for (int j=0;j<block.length();j++) {
                if (block.charAt(j)=='1') {
                    parity++;
                }
            }
            parity = parity % (int)Math.pow(2, parityLength);
            outStringBuilder.append(block).append(trimBinToLength(Integer.toBinaryString(parity),parityLength));
           
        }
        return outStringBuilder.toString();
    }
   
    public static String trimBinToLength(String in, int length) {
        if (in.length()==length) {
            return in;
        }
        if (in.length()>length) {
            return in.substring(in.length()-length);
        } else {
            while (in.length()<length) {
                in = "0"+in;
            }
            return in;
        }
    }
   
    public void initHuffman() {
        huffmanEncodeMap = new HashMap<>();
        huffmanDecodeMap = new HashMap<>();
        addHuffmanCode(" ","101");
        addHuffmanCode("e","1000");
        addHuffmanCode("o","0110");
        addHuffmanCode("\n","11111");
        addHuffmanCode("t","0000");
        addHuffmanCode("n","11100");
        addHuffmanCode("r","11011");
        addHuffmanCode("a","11010");
        addHuffmanCode(":","11000");
        addHuffmanCode("i","10011");
        addHuffmanCode(".","01110");
        addHuffmanCode("l","01011");
        addHuffmanCode("s","01010");
        addHuffmanCode("d","01000");
        addHuffmanCode("u","00111");
        addHuffmanCode("g","00011");
        addHuffmanCode("2","111101");
        addHuffmanCode("0","111100");
        addHuffmanCode("1","111011");
        addHuffmanCode("h","011111");
        addHuffmanCode("3","001101");
        addHuffmanCode("m","001011");
        addHuffmanCode("(","001001");
        addHuffmanCode("A","001010");
        addHuffmanCode(")","001000");
        addHuffmanCode("c","000100");
        addHuffmanCode("4","1110101");
        addHuffmanCode("k","1110100");
        addHuffmanCode("y","1100110");
        addHuffmanCode("b","1001011");
        addHuffmanCode(",","1001001");
        addHuffmanCode("w","1001000");
        addHuffmanCode("f","0111101");
        addHuffmanCode("p","0111100");
        addHuffmanCode("5","0100100");
        addHuffmanCode("D","0001010");
        addHuffmanCode("'","11001110");
        addHuffmanCode("P","11001011");
        addHuffmanCode("C","11001001");
        addHuffmanCode("v","11001000");
        addHuffmanCode("O","10010101");
        addHuffmanCode("6","01001110");
        addHuffmanCode("9","01001101");
        addHuffmanCode("7","01001011");
        addHuffmanCode("R","01001010");
        addHuffmanCode("8","00110011");
        addHuffmanCode("S","00110010");
        addHuffmanCode("T","00110000");
        addHuffmanCode("G","00110001");
        addHuffmanCode("H","00010111");
        addHuffmanCode("W","110011111");
        addHuffmanCode("E","110011110");
        addHuffmanCode("I","100101001");
        addHuffmanCode("M","010011111");
        addHuffmanCode("L","010011110");
        addHuffmanCode("-","010011001");
        addHuffmanCode("?","000101100");
        addHuffmanCode("Y","1100101011");
        addHuffmanCode("N","1100101010");
        addHuffmanCode("z","1100101000");
        addHuffmanCode(";","1001010001");
        addHuffmanCode("x","0100110001");
        addHuffmanCode("B","0100110000");
        addHuffmanCode("/","0001011010");
        addHuffmanCode("F","11001010010");
        addHuffmanCode("q","10010100000");
        addHuffmanCode("J","110010100110");
        addHuffmanCode("j","100101000011");
        addHuffmanCode("!","000101101100");
        addHuffmanCode("V","000101101101");
        addHuffmanCode("U","000101101111");
        addHuffmanCode("Z","100101000010");
        addHuffmanCode("X","11001010011111");
        addHuffmanCode("[","11001010011110");
        addHuffmanCode("Q","11001010011101");
        addHuffmanCode("]","0001011011101");
        addHuffmanCode("\"","0001011011100");
        addHuffmanCode("K","11001010011100");
    }
   
    public String huffmanEncode(String inputString) {
        String outString="";
        while (!inputString.isEmpty()) {
            for (String character : huffmanEncodeMap.keySet()) {
                if (inputString.startsWith(character)) {
                    outString+=huffmanEncodeMap.get(character);
                    inputString = inputString.substring(1);
                    break;
                }
            }
        }
        return outString;
    }
    public String huffmanDecode(String inputString) {
        String outString="";
        while (!inputString.isEmpty()) {
            boolean found=false;
            for (String binary : huffmanDecodeMap.keySet()) {
                if (inputString.startsWith(binary)) {
                    outString+=huffmanDecodeMap.get(binary);
                    inputString = inputString.substring(binary.length());
                    found = true;
                    break;
                }
            }
            if (found==false) {
                inputString = inputString.substring(1);
            }
        }
        return outString;
    }
   
    public void addHuffmanCode(String character, String binary) {
        huffmanEncodeMap.put(character, binary);
        huffmanDecodeMap.put(binary, character);
    }
   
    public String copyMultipleTimes(String in, int times) {
        StringBuilder outBuilder = new StringBuilder();
        for (int i=0;i<times;i++) {
            outBuilder.append(in);
        }
        return outBuilder.toString();
    }
    public String addErrors(String input, double errorChance) {
        int errorAmmount = (int)(input.length()*errorChance);
        boolean[] inputBoolean = new boolean[input.length()];
        for (int i=0;i<input.length();i++) {
            inputBoolean[i] = input.charAt(i)=='1';
        }
        for (int i=0;i<errorAmmount;i++) {
            inputBoolean[i] = (Math.round(Math.random()))>.5;
        }
        StringBuilder outStringBuilder = new StringBuilder();
        for (int i=0;i<input.length();i++) {
            outStringBuilder.append((inputBoolean[i] ? '1' : '0'));
        }
        return outStringBuilder.toString();
    }
    public String removeErrors(String input, int repetitions) {
        StringBuilder outStringBuilder = new StringBuilder();
        for (int i=0;i<input.length()/repetitions;i++) {
            int ones=0;
            for (int j=0;j<repetitions;j++) {
                ones += (input.charAt(i+j*(input.length()/repetitions))=='1' ? 1 : 0);
            }
            outStringBuilder.append((ones>repetitions/2?'1':'0'));
        }
        return outStringBuilder.toString();
    }
   
    public String removeErrorsUsingParityCheck(String input, int repetitions, int bitPerParity, int parityLength) {
        int blockLength = bitPerParity+parityLength;
        StringBuilder outStringBuilder = new StringBuilder();
        String[][] blocks = new String[repetitions][];
        boolean[][] blockValid = new boolean[repetitions][];
        int blockCount=0;
        for (int i=0;i<repetitions;i++) {
            String singleInput = input.substring((i*input.length())/repetitions,((i+1)*input.length())/repetitions);
            blockCount = (int)Math.ceil((double)singleInput.length()/blockLength);
            blocks[i] = new String[blockCount];
            blockValid[i] = new boolean[blockCount];
            for (int j=0;j<blockCount;j++) {
                String blockData;
                if ((j+1)*blockLength<singleInput.length()) {
                    blockData = singleInput.substring(j*blockLength,(j+1)*blockLength);
                } else {
                    blockData = singleInput.substring(j*blockLength);
                }
                blockValid[i][j] = blockValid(blockData,parityLength);
                blocks[i][j] = blockData.substring(0, blockData.length()-parityLength);
            }
        }
       
        for (int blockId=0;blockId<blockCount;blockId++) {
            for (int bitId=0;bitId<blocks[0][blockId].length();bitId++) {
                int ones=0;
                int valid=0;
                for (int repId=0;repId<repetitions;repId++) {
                    if (blockValid[repId][blockId]) {
                        valid++;
                        ones += (blocks[repId][blockId].charAt(bitId)=='1' ? 1:0);
                    }
                }
                if (valid==0) {
                    for (int repId=0;repId<repetitions;repId++) {
                        valid++;
                        ones += (blocks[repId][blockId].charAt(bitId)=='1' ? 1:0);
                    }
                }
                outStringBuilder.append((ones>valid/2?'1':'0'));
            }
        }
        return outStringBuilder.toString();
    }
   
    public boolean blockValid(String block, int parityLength) {
        int parity=0;
        for (int i=0;i<block.length()-parityLength;i++) {
            if (block.charAt(i)=='1') {
                parity++;
            }
        }
        parity = parity % (int)Math.pow(2, parityLength);
        String parityString = trimBinToLength(Integer.toBinaryString(parity),parityLength);
        for (int i=0;i<parityLength;i++) {
            if (block.charAt(i+block.length()-parityLength)!=parityString.charAt(i)) {
                return false;
            }
        }
        return true;
    }
}


Noch eine Anmerkung: Das Ganze hier ist absolut nicht auf Geschwindigkeit optimiert, weswegen ich zur Speicherung der Daten Strings verwende, die ich mit 0en und 1en befülle. Wäre das hier für ernsthafte Verwendung geschrieben gewesen, hätte ich die Daten in byte[] oder so gespeichert.
Gewinner der 6. und der 68. BlitzCodeCompo

BladeRunner

Moderator

BeitragMi, Feb 12, 2014 17:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi DAK,
sehr schöner Ansatz.
Eine Frage: Sehe ich das richtig dass Du in deinem Code eine feste Vorgabe für die Huffmann-Codes verwendest? Wird damit nicht der Sinn des Huffmann konterkariert - die jeweils aktuellsten Zeichen erhalten den kürzesten Code?
Mir ist klar dass bei kurzen Nachrichten die Codetabelle länger als die Nachricht wäre, aber wie würde dein Ansatz zum ermitteln der optimalen Tabelle aussehen?

(btw. - schön dass es sowohl hier als auch per PM so rege Teilnahme gibt. Dies ist ja kein Wettbewerb, einfach nur eine Knobelei, um so schöner dass ihr euch damit beschäftigt... Smile)
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

DAK

BeitragMi, Feb 12, 2014 18:58
Antworten mit Zitat
Benutzer-Profile anzeigen
@Huffman:
Man kann den Huffman so machen wie du meinst, also für jede Nachricht eine eigene Huffman-Tabelle erstellen, hat aber einen irren Overhead. Würde sich also erst auszahlen sobald man eine gewisse Menge Daten sendet. Außerdem wäre das für dieses Beispiel auch recht unpratisch, da sehr störanfällig. Wird dann einer der Huffman-Codes beschädigt, kann das dazu führen, dass die Übertragung komplett schief geht, obwohl die Nachricht selbst komplett unbeschädigt ist.

Wenn man noch eine bessere Komprimierung haben will könnte man auch einen adaptiven Huffman machen, wo der Huffman-Baum für jedes gesendete Zeichen neu berechnet wird. Das ist noch ein bisschen besser, aber auch deutlich fehleranfälliger (ein einziger falsch übertragener Buchstabe und alles danach ist beim Hugo).

Deswegen habe ich mich dafür entschieden, die Huffman-Codes fix zu lassen, da es auch so recht gut komprimiert ist, es keinen Verwaltungsoverhead gibt und es vergleichsweise stabil ist.


Ich habe noch mal nachgeschaut, wie lang der Beispielsatz wäre, wenn ich den Huffman-Baum direkt für diesen Satz berechne, und da komme ich auf 293 Bit, statt den 368 Bit, die ich mit fixer Tabelle habe. Das ist zwar etwas besser, aber dafür müsste man noch die Tabelle übertragen, die aus 108 Bit Huffman-Codes und 21 Buchstaben, die in ASCII (oder einer anderen beiden Teilnehmern bekannten Codierung) geschickt werden. Nimmt man 7-Bit-ASCII dann wären das 147 Bit ASCII-Daten, also insgesamt 255 Bit (schöne Zahl^^) Overhead. Dieser müsste mindestes so sicher geschickt werden wie die Nachricht selbst, was heißt, wir kämen auf 548 Bit Daten, was mehr ist als wenn man die Daten direkt in ASCII geschickt hätte.


Auch habe ich noch mal geschaut, ob die Huffman-Kodierung es überhaupt wert ist, bei der Übertragungsstörung und habe sie ein paar tausend Runden gegen ASCII 7-Bit und ASCII 8-Bit laufen lassen. Hier sind die Ergebnisse (alles ist mit 12 Bit Nutzdaten und 4 Bit Prüfsumme pro Block):
Code: [AUSKLAPPEN]

Huffman:
No Parity      : 318.0344/317.9576/317.658 => 0.9405
-> 1641 Bit
Normal Parity  : 11.3996/11.961/13.8594    => 0.0367
-> 2189 Bit


7Bit
Normal Parity  : 0.21                      => 0.0006
-> 3158 Bit
No Parity      : 212.37                    => 0.6283
-> 2366 Bit


8Bit
Normal Parity  : 0.23                      => 0.0007
-> 3608 Bit
No Parity      : 228.36                    => 0.6756
-> 2704 Bit


Huffman erhöht also die Fehlerrate, wird aber ein Teil der eingesparten Bits für Errorchecking verwendet verringert sich die Fehlerrate ungemein. Mit größeren Prüfsummen geht die Fehlerrate ziemlich schnell gegen 0.
Gewinner der 6. und der 68. BlitzCodeCompo

Tornado11

BeitragMi, Feb 12, 2014 19:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
   
 public String addErrors(String input, double errorChance) {
        int errorAmmount = (int)(input.length()*errorChance);
        boolean[] inputBoolean = new boolean[input.length()];
        for (int i=0;i<input.length();i++) {
            inputBoolean[i] = input.charAt(i)=='1';
        }
        for (int i=0;i<errorAmmount;i++) {                                       //falsch
            inputBoolean[i] = (Math.round(Math.random()))>.5;
        }
        StringBuilder outStringBuilder = new StringBuilder();
        for (int i=0;i<input.length();i++) {
            outStringBuilder.append((inputBoolean[i] ? '1' : '0'));
        }
        return outStringBuilder.toString();
    }


Ich wollte anmerken, dass (glaub ich) diese Funktion falsch ist. So wie ich das sehe, wird bei der Eingabe (Bit String mit Index 0...n-1) nur die (0... (n-1)*errorChance) Einträge verändert. Und weiterhin steht in der Aufgabenstellung Zitat:
Verrauscht bedeutet dass ein Byte durch ein zufälliges anderes ausgestuascht wird. Mit allen Konsequenzen.


D.h. es gibt immer "Burst-Fehler" der Länge 8 bit. Was du machst ist das ein Bit gedreht wird mit der Wahrscheinlichkeit (0<q<=1), ein sogenannter binary symmetric channel.

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group