Monday, November 21, 2005
/voodoo.css: 
#GeorgeWBush { position:absolute; bottom:-6ft; }

Gefunden als Sig im Thread Probleme mit Webshop Kunde. Ownedhausen, ja sowieso ;-)

Monday, November 21, 2005 3:46:41 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]

Das Solitaire Encryption Golfturnier war eine Challenge unter den Ägiden von Microsoft Österreich, unser Codefairway diente als bewährter Austragungsort für diesen MSDN Contest. Die Regeln und das finale Leaderboard sind ebendort nachzulesen - hier in diesem Blogpost sind die Post Mortems der Winning Entries zusammengetragen.

Die Post Mortems sind wie immer von den Golfern selbst verfasst, und werden hier ungekürzt und ungeschminkt nachgedruckt. Den optimierten Code kann man als angemeldeter Golfer im Leaderboard nachlesen (auch wenn's ohne diese Erklärungen nicht viel helfen wird <g />).

Platz 3, Claudia Krolopp

 Spät, aber doch ...

Im Gegensatz zu Franz bin ich absolut nicht der Meinung, dass das was hier verbrochen wurde selbsterklärend sein soll. Ich hab schon Probleme meine eigene Code-Zeile zu durchblicken.

Aber ich versuchs mal:

Bei mir muss als Kartenstapel kein string sondern ein int array herhalten.

Der Stapel wird mit 1 beginnend initialisiert, die beiden Joker erhalten beide den Wert 53 (an irgendeiner Stelle im Algorithmus muss für beide der gleiche Wert verwendet werden).

Heisst allerdings auch, dass die Position der Joker immer bekannt sein muss, deshalb werden bei jeder Veränderung im Stapel die Indices beider Joker (x und y) mitgezogen.

Sämtliche Verschiebungen werden in einer einzigen Funktion M( int j, int k ) durchgeführt, wobei immer die ersten j Karten k mal um 1 nach hinten geschoben werden. k wird returniert und wiederverwertet.

Sieht dann z.B. beim Verschieben einer Karte um 1 nach hinten so aus:

x=4;
     1234x5678y90
M(x,x);
     x12345678y90
M(1,k%53+1);
     12345x678y90

Mit k%53+1 funktioniert auch das Verschieben der letzten Karte reibungslos.

using S=System.String;
public class Tee
{
    // In "r" landet der verschlüsselte string, in "s" der key und 
    // "o" wird mit dem Alphabet in Grossbuchstaben initialisiert.

    S r,s,o;

    // Jede Menge Hilfsvariablen und das Kartendeck "a".
    int i,t,v,x,y,l,p,q;
    
int[]a=new int[54];

    // Hier werden j Karten k mal verschoben
    // in "x" und "y" werden die Positionen der Joker aktualisiert

    int M(int j,int k)
    {

        for(;j-->0;y+=y<1?k:y>k?0:-1,x+=x<1?k:x>k?0:-1)
            for(t=a[i=0];i<k;a[i]=t)
                a[i++]=a[i];

        return ++v>5?k:v%2>0?M(1,k%53+1):M(y,y);
    }

    // GenerateKeyStream generiert nicht nur den KeyStream sondern
    // auch gleich die verschlüsselte Nachricht

   

public S GenerateKeyStream(S P,S m)
    {
        // Bei der Initialisierung wird gleichzeitig "P" mit Ziffern angefüllt.
        // Damit ist es möglich beide Teile des Algorithmus, also über den ganzen
        // string "P" und bis die benötigte KeyStream-Länge erreicht ist, in 
       
// einer einzigen Schleife abzuarbeiten.

        for(y=l=p=0;y<53;P+=a[x=y]=a[++y]=y)
             o+=(char)(y%26+65);

        // Und hier wird nun endlich der ganze Algorithmus aufgerufen.
        // Der momentane Buchstabe in "P" wird auf Kartendeckwert runter-
        // gerechnet und in "q" gespeichert. 
        // War es ein Grossbuchstabe, dann ist q > 0 und die strings werden
        // nicht verändert.
        // War es eine der angehängten Ziffern, dann sind wird durch "P"
        // durch und können anfangen die strings zu basteln.
        // Wenn die Nachricht vieeeel länger als das passwort ist, kann es
        // allerdings sein, dass die angehängten Ziffern mengenmässig nicht
        // reichen (war bei mir anfangs der Fall) - dann kann "P" auch direkt
        // im if verlängert werden - kostet allerdings noch ein Byte extra
        // und wenns dem Tester so genügt ...

        

for(r=s="";l<m.Length;)
             if(M(q=P[p++]-64,M(a[M(M(x<M(x,x)?x:y,x>y?x:y)+1,53)],52))>(i=a[a[v=0]]-1)&q<1)
            
{
                 
s+=o[i];
                 r+=o[m[l++]-64+i%26];
             }

        // Ab jetzt isses wirklich selbsterklärend.

        return s;
     }

     public S EncryptData(S m,S k)
     {
         return r;
     }
}

Platz 2, Franz Polzer

Eigentlich ist der Code sowieso selbsterklaerend :)

c  Kartendeck
d  Keystream
e  Encrypted Message
f  lookup Table um (char) typecast und Offset von 'A' zu sparen
i  Startposition des zu verschiebenden Bereichs
z  Zielposition des zu verschiebenden Bereichs

using S=System.String;
public class Tee
{
        S c,d,e,f;
        int i,z;
        char j,u,l='A',a,b='5';
        public S GenerateKeyStream(S p,S m)
        {
                // Initialisieren des Kartendecks und der Lookup-Table
                for(;a<54;c+=++a)f+=l++;
                // Solange bis die Message encrypted ist
                for(;u<m.Length;)
                {
                        // Move der beiden Joker
                        for(l=b;l<=a;M(1))
                                z=((i=c.IndexOf(l))+l++)%b+1;
                        // Triple Cut
                        S[]k=c.Split(b,a);
                        c=k[2]+c.Trim((k[0]+k[2]).ToCharArray())+k[i=0];
                        // Countcut mit letztem Zeichen
                        z=52;
                        M(c[b]);
                        try
                        {
                                // Countcut mit Passphrase solange noch
                                // ein Zeichen da ist.
                                // Sonst -> Exception
                                M(p[j++]%64);
                        }
                        catch
                        {
                                // Auslesen des Zeichens fuer Keystream
                                // und erzeugen der encrypted Message
                                if(b>(i=c[c[0]>b?b:c[0]]))
                                        e+=f[(m[u]+(d+=f[--i%26])[u++]+1)%26];
                        }
                }
                // Keystream zurueckgeben
                return d;
        }
        public S EncryptData(S m,S p)
        {
                // Einfach die vorher berechnete Message zurueckgeben
                return e;
        }
        void M(int y)
        {
                // verschieben von y Zeichen von i nach z
                c=c.Remove(i,y).Insert(z<i?z:z-y+1,c.Substring(i,y));
        }
}

So, das war's eigentlich schon!

Platz 1, Thomas Gatterweh

/*
Die Idee.
Alle Veränderungen im Kartenstapel können durch eine Funktion ausgedrückt werden: Das Verschieben einer oder mehrerer Karten an eine andere Position im Stapel. Es müssen nur mehr die jeweiligen Start-, End- und Zielpositionen berechnet werden.
J
 
Die Joker.
Um ein Zeichen (";") zu sparen, wird die erste Jokerverschiebung nicht als erstes in der Schleife gemacht, sondern als letztes (im "for"). Das ist insofern möglich, da diese erste Jokerverschiebung im allerersten Durchlauf lediglich die beiden Joker vertauscht. (Der Stapel ist ja frisch aufgebaut.) Damit kann ich diese Vertauschung weglassen, und muss jetzt nur die Bedeutung von Joker #1 und #2 vertauschen. Deshalb hat Joker #1 den Wert 54 ("6") und Joker #2 den Wert 53 ("5").
 
Das Green.
Es lässt sich folgendes herausfinden:
a) Die Klasse "Tee" wird jeweils nur zum Verschlüsseln einer einzigen Nachricht benutzt. ==> Ich verwende soweit wie möglich die Defaultinitialisierung von Klassenelementen, z.B. int wird als 0 initialisiert.
b) "GenerateKeyStream" und "EncryptData" wird immer 'korrekt' paarweise benutzt. ==> Die Nachricht kann schon in "GenerateKeyStream" verschlüsselt werden. Die Parameter von "EncryptData" setzte ich einfach als korrekt voraus.
*/
using S = System.String;
public class Tee
{
        
/*
         "a" enthält in den ersten 54 Zeichen den Kartenstapel; der Rest bis Zeichen 90="Z" wird zum Wandeln einer Zahl in ein Zeichen verwendet.
         "k" ist der KeyStream.
         "e" ist die verschlüsselte Nachricht.
         */
         S a, k, e;
        
/*
         "i" ist die Position des Jokers #1, "j" die des Jokers #2. "j" wird gleich am Anfang gebraucht und muss initialisiert werden.
         */
         int h, i, j = 52, l, n;
        
/*
         "x" enthält a) das Zeichen des Jokers #2 (siehe oben) und auch b) 53, d.h., 1-Anzahl der Karten.
         "y" enthält in der Hauptschleife a) das Zeichen des Jokers #1 und auch b) 54, d.h., die Anzahl der Karten.
         Zuerst wird "y" allerdings zum Initialisieren von "a" verwendet. Der Defaultwert von 0 passt dafür hervorragend.
         */
         char x = '5', y;
        
/*
         "EncryptData" liefert nur mehr die bereits generierte verschlüsselt Nachricht zurück.          */
         public S EncryptData( S m, S k )
         {
                  
return e;
         }
        
/*
         "C" verschiebt einen Kartenstapel, gegeben durch die Position "s" der ersten Karte und "e" der letzten Karte (exklusiv), an die Position "z".
         Ist "s" größer oder gleich "e", wird nichts verschoben.
         "i" und "j" wird mit der neuen Position des 1. und 2. Jokers aktualisiert.
         */
         void C( int s, int e, int z )
         {
                   a = a.Remove( s, e -= s < e ? s : e ).Insert( z, a.Substring( s, e ));
                   i = a.IndexOf( y );
                   j = a.IndexOf( x );
         }
        
/*
         "GenerateKeyStream" verschlüsselt auch noch gleich die Nachricht und hebt sich das Ergebnis für "EncryptData" auf.
         */
         public S GenerateKeyStream( S p, S m )
         {
                  
// Ein Kartenstapel muss her...
                   for( ; y < 90; )
                            a += ++y;
                  
// Jetzt noch schnell "y" initialisiert, und dann kann es losgehen bis alle Zeichen da sind...
                   for( y = '6'; n < m.Length; C( i, 1 + i, i % x + 1 ))
                   {
                           
// Jokerverschiebung (am Ende des "for" für Joker #1, bzw hier für Joker #2)
                            // Von alter Jokerposition eine Karte an die neue Position verschieben.
                            C( j, ++j, j % x + 1 );
                           
// TripleCut in zwei Schritten...
                            // Wo ist der vordere Joker?
                            h = i < j ? i : j;
                           
// 1. Schritt: Die Karten von der Karte nach dem hinteren Joker (wenn "h" der vordere ist, dann ist "i+j-h" der hintere!) bis zum Ende an die Position vor dem vorderen Joker verschieben.
                            C( i + j - h + 1, y, h );
                           
// 2. Schritt: Die Karten vom Anfang bis zum (ursprünglichen) vorderen Joker ans Ende verschieben.
                            C( 0, h, y - h );
                           
// CountCut gemäßder letzten Karte
                            // Invers zur Beschreibung: Ich verschiebe nicht die N ersten Karten unmittelbar vor die letzte Karte, sondern verschiebe die Karten von der N-ten bis zur vorletzten an den Anfang.
                            C( a[ x ], x, 0 );
                           
try
                            {
                                     
// CountCut nach dem nächsten Zeichen in der PassPhrase. Gibt's dort keines (mehr), geht's per Ausnahme zur Ausgabe...
                                      C( p[ l++ ] - 64, x, 0 );
                            }
                           
catch
                            {
                                     
// Ausgabekarte holen, und wenn kein Joker...
                                      h = a[ a[ 0 ] < x ? a[ 0 ] : x ];
                                     
if( h < x )
                                      {
                                              
// ...dann Message verschlüsseln...
                                               e += a[( h + 13 + m[ n++ ]) % 26 + 64 ];
                                              
// ...und KeyStream erzeugen.
                                               k += a[ --h % 26 + 64 ];
                                              
// Beide Male wird der unverändert bleibende Teil des Kartenstapels (alles außer den ersten 54 Zeichen) zum Umwandeln des Kartenwertes in ein Zeichen verwendet.
                                      }
                            }
                   }
                  
return k;
         }
}
 

Monday, November 21, 2005 3:38:27 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Saturday, November 19, 2005

Aus gegebenen Anlaß - die ersten Schneefälle und das zugehörige Chaos auf den Strassen - wollte ich vermerken daß der Termin steht (außerhalb sämtlicher Ferien die die An- oder Abreise trüben könnten), und auch das Programm finale Formen annimmt. Das Wintercamp 2006 kann kommen!

Freitag Wie gehabt unzeremonielles Absumpfen im Bodennebel. Treffpunkt Tekin (Bistro Oriental) ab 19 Uhr auf ein Abendessen und erstes Bier.

Samstag Aus gesundheitlichen Gründen wird Schlittenfahren abgesagt (Scherzchen). Aber diesmal unterschreibt jeder für den Schlitten, den er mitnimmt - damit diesmal auch wieder alle Schlitten den Weg von der Hütte nach unten finden ;-) Das war ja wirklich heuer die Höchststrafe. Alternativ gibt es auch wieder Skifahren in Dachstein West, vielleicht diesmal mehr Delinquenten? Ich bin auch brav und halte mich zurück...

Samstag Abend Damit diesmal nicht gestresst werden muß, beginnt das Abendprogramm erst um 18 Uhr. Es geht zum Grabnerwirt. Würde ich uneingeschränkt als "einheimisch" bezeichnen, wir werden uns Platz reservieren plus für Interessierte auch Holzknechtnocken (Hinweis: dürfte nicht jedermanns Sache sein). Die Reservierung für diesen Teil des Programms wird zeitnah stattfinden, wollte es Euch aber schon mal wissen lassen.

Sonntag Der Ausklang (Wo ist mein Parkemed / Thomapyrin?). Vielleicht fällt mir da noch was ein, Ausflugsmäßig.

Wo findet das Event statt? Wie immer in Bad Ischl, Oberösterreich. Hier ist der BLfH heimisch, und die Location hat sich bis dato sehr bewährt. Technisches Rahmenprogramm ist wie immer keines geplant, bei dem einen oder anderen Schnapstee beim Judy wird sich sicherlich eine technische Diskussion nicht vermeiden lassen ;-)

Weitere Details werden noch bekannt gegeben. Alte Events in Wort und Bild:

Saturday, November 19, 2005 11:35:56 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Tuesday, November 15, 2005

Normalerweise bekomme ich ja nur bei diversen elektronischen Gadgets einen Gieranfall (könnte man ja mit "professionellem Interesse" entschuldigen), allerdings hat man ja auch Hobbies, und da ist schönes Gerät auch von Interesse.

So zum Beispiel beim ergo_bike premium8i, einem Hometrainer für völlig Verrückte: 1000 Watt (wozu, ich maxe nicht mal meinen 4008er TRS aus, und der hat 400 Watt)! Der Rest der Package ist zumindest auch für den Geek in mir ganz witzig: USB Anschluß, optionale Netzwerkanbindung (RJ-45!), MP3 Player fütterbar via SD Karte, 40MB freier Hauptspeicher (ob man das Ding hacken kann?) sowie natürlich ein Farbdisplay. Man sollte das Hometraining definitiv ernst meinen wenn man sich das Gerät zulegt.

Tja, das wird auf der Wunschliste verbleiben, hab' mir heuer ja schon zwei neue Rennräder geleistet (war auch so ein Gieranfall).

Tuesday, November 15, 2005 10:19:49 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Monday, November 14, 2005

Klaus Aschenbrenner veranstaltet diesen Winter das SQL Server 2005 Community Bootcamp (ist wohl am CBC05 auf den Geschmack gekommen). In seinem Blogeintrag gibt es zusätzliche Infos - das wichtigste vorweg: Ort ist Wien, Österreich. Es erweist sich ein weiteres Mal daß die Community in Österreich sehr aktiv ist!

Monday, November 14, 2005 10:20:04 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]

BLUNZN.COM - Blunznfett im Internet

Gefunden weil mir fad war und ich "blunzn" in Google eingegeben hab'. Ein wahrer Quell an Zeitverschwendung.

Monday, November 14, 2005 10:15:54 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Wednesday, November 02, 2005

Aber seit heute bei mir im Bücherregal: Rechtsberatung Internet

Wednesday, November 02, 2005 10:08:09 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
 Tuesday, November 01, 2005
Ja, ja. Drahtlos ist sie, die schöne neue Welt. PDAs, MDAs, Laptops, Palmigotchis, Schwarzbeeren, WLAN, Blauzahn, Wimax etc... Glaubt man den Marketingfuzzis, so schweben wir alle selig von jeglichen Drahtfesseln befreit mit unseren Juppispielzeugen einher, dämlich grinsend und jeden Furz in unser immer verbundenes Autschlook oder Lotus tutdesNotes mit der neuesten Stifttechnologie oder Nanotastatur oder gar auf einer virtuellen Tastatur eintragend. Hah! Da lachen ja die noch nicht vergrippten Hühner. *So* sieht die Wirklichkeit aus:

 


Und da sieht man noch nicht das Palmigotchi, die USB-hubs, die CAT5-kabel, die zweite Steckerleiste und die beiden Laptops...

P.S.: der nächste grosse Schnirch kommt bestimmt - das hier ist nur ein Lückenbüsser bis ich Zeit und Musse finde. Und mich aufraffe über unsere neue, grossartige, tolle Onlineverwaltungssaftware zu berichten.

Tuesday, November 01, 2005 7:32:17 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]

Liebes Tagebuch!

Ich muß mich mal wieder an deiner starken Schulter ausweinen. Der Grund, frägst Du?  Der letzte Tag meines Urlaubs auf den Kanaren.

Weil mein samstäglicher Rückflug ab Teneriffa Reina Sofia frühzeitiger als alle gangbaren Fährverbindungen abging (ich weilte auf Gomera, Valle Gran Rey, La Calera), hab’ ich mir für Freitag auf Samstag ein Hotel in der Nähe von Los Cristianos gesucht, dem Fährhafen von Teneriffa. Sol Sun Beach Apartments am Playa Fanabe, gebucht, wie es sein soll, via Internet.

Mir kam schon bei der Taxifahrt zum Hotel der leise Gedanke, daß dies der in Beton gegossene Pauschalterroristenurlaubshorrorort sein könnte. Es hätte mich ja vor Betreten des Hotels schon mißtrauisch stimmen sollen, daß die Lokale die ich bis dorthin sah ein englisches Brechfest als erstes auf der Karte stehen hatten.

Wie recht ich leider hatte! Mit einem Buch unter dem Arm (Professional Software Development, ich disqualifiziere mich gerne im Urlaub) dachte ich „suchst Dir halt ein Beisl auf einen Kaffee und Bocadillo“. Denkste. Erstens kommt es anders, zweitens als man denkt.

Kaum an der Strandpromenade angekommen sehen meine geröteten Augen einen Würger King. Um die Augen auszuruhen ein Blick in die Ferne – oh Unheil, natürlich gibt es hier auch einen McVomit. Aufgeben gilt ja nicht, daher eine Etage tiefer, und die ganzen Lokale inspiziert. Alles Englisch, und die abendlichen Fußballspiele sind angeschrieben. Inselaffen sind also hier zugange. In Mengen.

Mit dem Tag habe ich abgeschlossen, allerdings wollte ich zumindest an der lautesten Adresse des Platzes Abendessen (suizid angehaucht der BLfH, aber pathologische Erlebnisse haben auch ihren Reiz). Um mir wenigstens nicht die geschmackliche Erinnerung zu versauen eine Mafiatorte eingeworfen. Bei der Rechnungslegung sollte allerdings nachgebessert werden: mit südlicher Einstellung war das nicht zu erklären, sondern eher mit Servicio auf Augenhöhe mit den Servisios.

Das ganze kann man übrigens locker toppen – man muß nur mit der „richtigen“ Truppe im Flieger retour sitzen... so geschehen im Niki Flieger nach Salzburg, wo die Touris beim Landen als auch nach der darauffolgenden „Begrüssung“ der Stewardess in Salzburg geklatscht haben. Manchmal, nur manchmal möchte ich im Boden versinken. Pauschaltouristen extraordinaire.

Was sonst noch aufgefallen ist

  • daß auf Gomera ein Renault Clio Williams wirklich Sinn machen kann
  • daß Spritpreise a la 68 Cent pro Liter Diesel dem gelernten Österreicher die Tränen in die Augen treibt
  • daß der Klopapierverbrauch eine Funktion der Verfügbarkeit zu sein scheint (je mehr vorhanden ist, desto rapider ist der Verbrauch)
  • daß Sperrflächen in Spanien scheints generell als Parkfläche mißbraucht werden, was bei der Einfahrt in den Kreisverkehr die Sicht allerdings sehr beschränkt
  • daß man sich vorher genauer über die Lage der Unterkunft erkundigen sollte, weil dann erspart man sich die Kofferschlepperei sogar ganz (gell, Claus?)
  • daß wenn man Urlaub auf einer Deutsch-verseuchten Insel macht, man daran denken sollte, daß die quasi alles reservieren was nicht schnell genug wegrennt
  • daß man um 40 Euro auch länger als eine Stunde Taxi fahren kann (San Sebastian de Gomera nach Valle Gran Rey)
  • daß bergauf ein LKW schneller sein kann als Du. Und zwar viel schneller.
  • daß ich zum ersten Mal seit Urlaubsgedenken meine ehrgeizigen Pläne punkto Lesestoff durchgebracht habe
  • daß ich mich mit Batidos und Bocadillos angefüllt habe wenn’s denn irgendwie ging. Frische Mango, Chirimoya, Guave oder Maracuja sind einfach zu lecker.
  • daß ich meine Lokaltips sicher nicht publizieren werde, ein Geheimtip bleibt eben nur dann ein Geheimtip wenn er geheim ist
  • daß ich genau deswegen jetzt verschärftes Hometraining vor mir habe. Der Gourmand Gourmet hat wieder zugeschlagen
  • daß der BLfH wieder da ist, fürchte Dich!
Tuesday, November 01, 2005 4:22:28 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Friday, September 30, 2005
Seit 23 Uhr läuft das aktuelle Golfturnier, das diesmal (a) anspruchsvoll ist, (b) ensprechend Zeit läßt, (c) schöne Preise für die Gewinner bietet. Bernd und Ich freuen uns, das zusammen mit Mario Szpuszta von MS Österreich auf die Füße gestellt zu haben. Viel Spaß!
Friday, September 30, 2005 10:30:36 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Tuesday, September 20, 2005
Während ich einem neuen Schnirch gefasst ins Auge sehe, gibts wenigstens einen kleinen Lichtblick: Rekursion im echten Leben. Den Schlüsselanhänger mit einem Delphin im Delphin bekam ich neulich beim Chinesen des Vertrauens (Mittagsbüffet um 5,50 nach dem Motto "Friss bisste platzt, platzen tuste nicht, also friss!").


Tuesday, September 20, 2005 3:25:54 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]