Tuesday, January 24, 2006

Die Nachschau zum Wintercamp 2006 ist fertig. Lesen, staunen und beim nächsten Mal dabei sein!

Und Bilder und ein Video gibts auch auf der Hauptseite. Wird dort das Rätsel der SMS gelüftet?

Tuesday, January 24, 2006 7:34:29 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Sunday, January 22, 2006

Die Geschichte (Nachbericht) ist noch im Werden, ein Foto wollen wir aber vorausschicken:

PS - Mit C0006 hat es das folgende auf sich:

Community Wintercamp 2006
Community WC 06
Community 00 06
C0006

Sunday, January 22, 2006 7:24:07 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Sunday, January 08, 2006
Sunday, January 08, 2006 8:51:27 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]

So oder ähnlich könnte die Überschrift eines Artikel in der Deutschen liebsten Tageszeitung lauten in bezug auf die Vorkommnisse vorgestern Abend gegen 20 Uhr in meiner Wohnung. Was geschah am Tatort?

Nun, Eurosport (unabkömmlich für den Rennrad-Interessierten) wechselt die Frequenz. Ergo - Sendersuche. Allerdings - er findet ihn nicht. In letzter Konsequenz (viele, viele unschöne Worte dazwischen einfügen) daher Restore Factory Defaults plus alle Kanäle gelöscht. Neue Sendersuche. Juhuu! Da ist der wieder, der Eurosport.

Gut, also die Sender wieder so organisieren wie vor der Löschung. Und wie es der 666er so will, drücke ich knapp vorm Fertigsein auf das Exit-Tästchen. Ungläubiges Staunen. Ist ja wohl nicht wahr, ich bin draussen! (frei nach BoRRRis) Die haben dem Mistding von SAT Receiver nicht mal eine Yes/No/Cancel (pun intended) Abfrage spendiert ob ich denn die im Schweiße meines Angesichts gemachten Änderungen an der Senderliste wirklich, ganz definitiv das Klo runterspülen will. Säcke. Töten, töten, töten!

Tja, und da ist mir dann die Fernbedienung ganz unglücklich aus der Hand gerutscht. Und fünf Meter weiter tragisch am Boden zerschellt. Sellerie.

Sunday, January 08, 2006 12:08:14 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
 Thursday, December 22, 2005

In diesem Sinne ein frohes Fest an die Community! Auf daß wir uns nächstes Jahr genauso froh und munter wiedersehen.

Thursday, December 22, 2005 3:37:42 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [8]
 Saturday, December 17, 2005
Nun singen wir alle im Chor (zur Melodie von "Jingle Bells"):

"Microsoft, Microsoft gives some gifts away,
Microsoft, Microsoft, you really made my day"

Anlass? Das formschöne, praktische Geschenk hier:




Ein Winzweihnachtsbaum! Mit USB-anschluss. Wenn da wenigstens ein Speicherchip drin wäre...

(singt falsch und laut)

"Alle Jahre wieder bringt das Billykind uhuhuns Geschähänke, die nicht von Nöten sind..."

Und wieder ein USB-port belegt.

Saturday, December 17, 2005 5:19:24 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Wednesday, December 14, 2005

Ab sofort sind alle Informationen zu diesem Event auf einer Homepage gesammelt:

http://www.dotnetgerman.com/Community/Wintercamp2006/

Wednesday, December 14, 2005 2:58:52 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 Wednesday, November 23, 2005

Während Mario's letzter Session gestern auf der Launch Conference 2005 in Wien gab's die erste Live-Preisverleihung bei einem .NET Golfturnier. Auf die ersten drei Plätze gegolft hatten sich Thomas Gatterweh, Franz Polzer und Claudia Krolopp. Bevor Mario zur Preisverleihung schritt (und das dekorative Snowboard damit die Bühne verließ), habe ich der versammelten Entwicklergemeinde kurz und prägnant das Golfkonzept vorgestellt.

Zumindest der Part, daß man keinerlei Coding Style Guidelines einhalten muß, dürfte einigen Programmierern gefallen haben.

Natürlich durfte das Leaderboard nicht fehlen:

Danach ging's zur Preisverleihung, beginnend mit Claudia, die den MP3 Player bekam:

Dann betrat Franz die Bühne, um das Snowboard abzuholen (man bemerke den Code auf der Slide, unkommentiert - die Post Mortems sind hier zu finden):

Thomas erhielt einen MDA sowie (demnächst) ein Visual Studio Pro (das Foto wurde leider nichts, sorry).

Das nächste Turnier kommt bestimmt, und es wird mit .NET 2.0 ausgetragen werden!

Wednesday, November 23, 2005 2:47:12 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
 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]