Entwickler-Ecke

Open Source Projekte - Das Nachrichten-Rätsel. Die Auflösung.


Gausi - Sa 09.12.06 12:55
Titel: Das Nachrichten-Rätsel. Die Auflösung.
Das Nachrichten-Rätsel. Die Auflösung.


Die Nachricht kam natürlich von Mr.Spock und lautete "Lebe lang und in Frieden". Ich möchte jetzt übrigens nicht darüber streiten, ob das die angemessene Übersetzung des englischen Originals "Live long and prosper" ist, oder ob es besser "Lebe lang und erfolgreich" heißen muss.

Mit dem ersten Tipp war klar, dass die Nachricht ein Bild ist. Beim zweiten Hinweis war das Stichwort "Arecibo-Botschaft" das Wichtige, denn dort wurde dasselbe Prinzip angewandt. Ein Bild, dessen Höhe und Breite einer Primzahl entspricht, wurde in eine einfache Abfolge von Nullen und Einsen transformiert. Für die Anordnung als Bild gibt es dann nur zwei Möglichkeiten, da die Länge dieser 0-1-Folge gerade das Produkt zweier Primzahlen ist.
Außerirdische Lebensformen sind natürlich technisch etwas weiter wie wir und begnügen sich nicht mit Schwarz-Weiß-Bildern, sondern senden in Farbe. Daher kam die Nachricht nicht als 0-1-Folge bei uns an, sondern als Folge von RGB-Werten, die sich mit Delphi recht einfach zu einem Bild zusammenfügen lassen.

Und für die wenigen, die Mr.Spock und Star Trek nicht kennen: Das Bild findet man ganz leicht über die Google-Bildersuche.

Im Anhang findet ihr eine mögliche Lösung. In dem Projekt ist auch der Code zur Erzeugung einer solchen Nachricht aus einem Bild enthalten. Die entsprechenden Buttons sind aber der Übersichtlichkeit halber disabled.

Andere Lösungsansätze für diese Aufgabe können wieder in diesem Thread geposted und/oder diskutiert werden.


Chryzler - Sa 09.12.06 13:04

Danke für die Auflösung. An die Primzahl hatte ich gar nicht gedacht, hab einfach solange die Breite und Höhe ausprobiert, bis ein anständiges Bild rauskam.


Christian S. - Sa 09.12.06 13:07

Hier das ganze noch als C#-Programm :-)

Die Nachricht bitte aus dem ersten Beitrag nehmen ;-)


coder62 - Sa 09.12.06 13:10


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
<?php
$handle = fopen ("./Nachricht.txt", "r");
$i = 0;
$i2 = 0;
header ("Content-type: image/png");
$im = @imagecreatetruecolor (253, 199);
$background_color = ImageColorAllocate ($im, 255, 255, 255);
$pixel_color = array();
while (!feof($handle)) {
  $rrgb = translate(trim(fgets($handle, 4096)));
  if(!isset($pixel_color[$rrgb[0].$rrgb[1].$rrgb[2]])){
    $pixel_color[$rrgb[0].$rrgb[1].$rrgb[2]] = ImageColorAllocate ($im, $rrgb[0],$rrgb[1],$rrgb[2]);
  }
  imagesetpixel($im,$i2,$i,$pixel_color[$rrgb[0].$rrgb[1].$rrgb[2]]);
  if($i2 == 263){
    $i++;
    $i2 = 0;
  }
  $i2++;
}

ImagePNG ($im);
fclose ($handle);

function translate($zahl){
  $rgb = array();
  $hexv = dechex($zahl);
  while(strlen($hexv)<6){
    $hexv = '0'.$hexv;
  }
  $rgb[0] = hexdec(substr($hexv,0,2));  
  $rgb[1] = hexdec(substr($hexv,2,2));  
  $rgb[2] = hexdec(substr($hexv,4,2));
  return $rgb;  
}
?>


das ist meine lösung mit php erstellt, fands lustig hatte erste 350 inner breite (durch ausprobieren), man konnte das bild trotzdem erkennen sah nur hologrammässig aus und spock war mehrfach zu sehen :P


Dragonclaw - Sa 09.12.06 13:41

Ich habs so gemacht. Wollte eigentlich auch erst den Text in ne Listbox laden und von da aus. Das ist aber sehr langsam. Direkt aus der Datei lesen ist, meiner Meinung nach viel schneller. Die Weite hab ich halt rausgefunden in dem ich einfach ne Schleife hab laufen lassen die das Bild immer und immer wieder zeichnet, jeweils immer einen pixel breiter.

Hier der Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.Button1Click(Sender: TObject);
var s, dir : String;
    i : Integer;
    f : TextFile;
begin
x := -1; y := 1; weite := Edit1.text; dir := 'Nachricht.txt';
AssignFile (f, dir);
Reset (f);
while not EOF(f)do
  begin
    ReadLn(f, s);
    inc(x);
if x > weite then
  begin
  x := 0;
  inc(y);
  end;
  Form1.Canvas.Pixels[x,y]:=strtoint('$' + inttohex(strtoint(s),2));
end;
end;


F34r0fTh3D4rk - Sa 09.12.06 13:42

ich hab die breite nicht durch probieren oder durch primzahlen herausbekommen, sondern dadurch dass die differenz an einem punkt der grafik ziemlich groß ist, und zwar immer dann wenn eine neue reihe anfängt und dieses intervall ist die breite. das muss aber nicht auf jedes bild zutreffen.

mfg


elundril - Sa 09.12.06 13:42

die falle mit "Contact" mit Jodie Foster war fies. da ist das signal von Wega gekommen und war primzahlen.

lg el


F34r0fTh3D4rk - Sa 09.12.06 13:51

wieso war das ne falle ? man sollte die lösung ja anhand der tipps finden und nicht einfach erraten ;)

mfg


GTA-Place - Sa 09.12.06 14:00

user profile iconDragonclaw hat folgendes geschrieben:

Delphi-Quelltext
1:
Form1.Canvas.Pixels[x,y]:=strtoint('$' + inttohex(strtoint(s),2));                    

Kürzer:

Delphi-Quelltext
1:
Form1.Canvas.Pixels[X, Y] := StrToInt(S);                    


elundril - Sa 09.12.06 14:03

war ja ein tipp! :-(
das war harte arbeit das zu recherchieren.

lg el


delfiphan - Sa 09.12.06 14:15

Im Anhang mein Image-Loader mit integrierter Bildgrössenerkennung (Primfaktorenzerlegung+Korrelationstest für Breit-/Hochformat; Das Bild könnte natürlich noch auf dem Kopf sein, oder gespiegelt, oder gedreht. Das kann das Programm natürlich nicht automatisch erkennen ;)).
PS: Mathematisch gäbe es noch zwei weitere (etwas unsinnige) Lösungen: 1 ist ein Faktor, somit könnte das "Bild" auch ein Einzeiler sein.


Lannes - Sa 09.12.06 15:03

Hallo,

Die Bildgrößenerkennung sah bei mir so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  i := Memo1.Lines.Count;
  //vom Quadrat zum Rechteck
  for z := round(sqrt(i)) downto 1 do
    if Trunc(i/z) = i/z then
    begin
      F_X := Trunc(i/z);
      F_Y := Trunc(i/F_X);
      break;
    end;


@Gausi: Da fehlt noch liste.Free :wink:


Heiko - So 10.12.06 21:12

Im Anhang mein Lösungsproggi, wobei das Berechnen der Größe erst im Nachhinhein reinkam (war zuerst zu faul das reinzunehmen, da ich immer leiber probiere (wobei lustige effekte rauskamen)) ;).

Kann mir z.B. einer sagen, wo die Handfläche von
user defined image
hier hin ist, denn unten fehlt müssten da noch ein paar Pixelreihen eigentlich hin, aber das Bild ist nicht größer :gruebel: ?:
user defined image


jakobwenzel - So 10.12.06 21:35

so ein xor $FF hätte (ohne die Entschlüsselung) doch noch schön ausgesehen :mrgreen: :
user defined image


jaenicke - So 10.12.06 22:05

Tja, ich hab die Größe ähnlich wie user profile iconF34r0fTh3D4rk herausgefunden...
Ich habe einen Wert gesucht, der dem des ersten Pixels ähnlich ist und der sich von dem vorherigen deutlich unterscheidet.

Jedenfalls habe ich jeden Wert in einen Integer umgewandelt und dann diese Werte nacheinander in einen Stream geschrieben.
Die resultierenden Daten habe ich dann als RAW-Daten in Paint Shop Pro geladen und die ermittelte Breite von 263 Pixel angegeben. Was dabei herauskam seht ihr unten... Es reichte mir um Spock zu erkennen ;-).
user defined image
Mit etwas anderen Parametern habe ich inzwischen bessere Ergebnisse erhalten, aber ans Originalbild kommt das nicht mal annähernd heran.


jakobwenzel - So 10.12.06 22:19

Ich glaub das Bild war zeilenweise aufgebaut und du hasts spaltenweise eingelesen.
Probier mal als Breite 200.


jaenicke - So 10.12.06 22:27

Dann ist gar nix zu erkennen ;-). Naja, da gibts einige Einstellmöglichkeiten, ich glaube ich habe alle durchprobiert.


Heiko - Mo 11.12.06 07:30
Titel: Re: Das Nachrichten-Rätsel. Die Auflösung.
Einen kleinen Fehler in Gausis Lösung gefunden :mrgreen:

user profile iconGausi hat folgendes geschrieben:
Daher kam die Nachricht nicht als 0-1-Folge bei uns an, sondern als Folge von RGB-Werten

Die angaben in der Datei waren nicht RGB, sondern BGR ;).


delfiphan - Mo 11.12.06 07:50

In Intel-Chips mit little endian wird $0000ff als Bytefolge ff 00 00 gespeichert.


BenBE - Mo 11.12.06 16:22

So sah mein in die Tastatur gehackter Source aus ...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.Edit1Change(Sender: TObject);
var
    X:Integer;
    A, B: Integer;

    f: Textfile;
begin
    X := StrToIntDef(Edit1.Text, 228);

    AssignFile(F, 'nachricht.txt');
    Reset(F);
    B := 0;
    While not EOF(f) do
    BEgin
        ReadLn(F, A);
        Canvas.Pixels[B mod X, B div X] := A;
        Inc(B);
    end;
    CloseFile(F);
end;


Einfach ein Edit auf's Form ziehen und die Breite eintragen ...

Edit: Die 228 ist die Wurzel der Pixelanzahl ...


jakobwenzel - Mo 11.12.06 16:52

Bei mir siehts genau so aus, nur dasses bei mir ein SpinEdit ist und dann die Konvertierung entfällt und das was bei dir A ist, ist bei mir ein String und wird mit StringToColor konvertiert.


Leuchtturm - Mo 11.12.06 19:12

Ich weiß zwar was der Code macht ich habe aber nicht so richtig verstanden warum jetzt das bild erzeugt wird :nixweiss:


Heiko - Mo 11.12.06 19:46

Hallo,

dass ist doch ganz einfach. Und zwar ist jede Zeile der Datei ein BGR-Wert (den du also direkt als Pixel in Delphi verwenden kannst). Da ein Bild normalerweise rechteckig ist suchst du alle möglichen Paare, die die Gesamtpixelanzahl ergibt, also hier die 199*x (weiß die Zahl nimmer) und x*199. Die mit 1*v und v*1 sind sinnlos - dürfte ja klar sein.
Jetzt weißt du, wie groß das Bild ist und zeichnest die Pixel einfach nur noch reihenweise. Mehr steckt nicht dahinter.


delfiphan - Mo 11.12.06 20:11

@Heiko: Wie kommst du auf BGR?


jakobwenzel - Mo 11.12.06 20:26

Little Endian, steht hier auch schon irgendwo. :lupe:


delfiphan - Mo 11.12.06 21:05

Ich würde mal sagen es ist weder einfach RGB noch BGR sondern abhängig von der Interpretation des Senders/Empfängers. RGB für Windows ist nicht gleich RGB für OpenGl. Die sind genau umgekehrt definiert. Das ist ne Definitionssache.
Verwenden Aliens Intel-Chips, so wurde $BBGGRR als Bytefolge $RR $GG $BB versendet, also RGB.


GTA-Place - Mo 11.12.06 21:06

Er kam auf BGR, weil er ScanLine benutzt hat und vergessen hat, dass Scanline mit BGR statts RGB arbeitet ;-).


Heiko - Mo 11.12.06 21:07

Jo, ist Geschmackssache, wobei ich mir BGR angewöhnt habe, denn wenn den RGB-Hex-Wert aus Zeichenprogrammen rauskopiert und beim WinEditor in Dezimal umwandelt erhält man das Gegenteil von dem, was man haben möchte ;).