(?-?-?-?) RESULT: NaN

Neurodeamon

Erfahrenes Mitglied
Das Ziel der Codespielerei dürfte wohl jeder aus seiner Kindheit kennen: Die berühmte Cäsar Verschlüsselung. Jeder Buchstabe eines Wortes (oder Satzes) wird im Alphabet um n Zeichen verschoben - zyklisch. Ich denke, jeder kennt die zwei Scheiben mit Alphabet, die durch drehen verschlüsseln, bzw. entschlüsseln.

Mit ein wenig Hilfe aus dem Forum habe ich folgendes Script geschrieben. Seltsamerweise bekomme ich vom Mozilla JS-Debugger keine Fehlermeldung (der IE übrigens auch nicht) sondern nur einen "NaNNaNNaNNaNNaNNaNNaNNaN"-String zurück. Irgendwo ist ein Fehler, den ich nicht finde.

Die Verschlüsselung ist natürlich auf 1:1 Übergabe des Strings gesetzt, damit man auch den 'verschlüsselten' Originalstring als Ergebnis erhält.

Mein PHP-Script war in 20 Minuten fertig, an diesem JS-Script sitze ich schon 2 Tage *kotz* :)

Code:
<script type="text/javascript">
<!--
function fInit(){
    sChars = new String("abcdefghijklmnopqrstuvwxyz-");
    aChars = new Array();
    for(i = 0; i<sChars.length; i++){
        aChars[i+1] = sChars.charAt(i);
    }
    iCharslength = sChars.length;
    return iCharslength;
}
function fFind(sSearch){
    for(var x=0; x<this.length; x++){
        if(this[x] == sSearch){
            var iIndex = x;
            return iIndex;
        }
    }
    return -1;
}
Array.prototype.find = fFind;
function fInject(sMail, sKey){
    fInit();
    aMail = new Array();
    aResult = new Array();
    var sResult = "";
    for(var y=0; y<sMail.length; y++){
        aMail[y+1] = sMail.charAt(y);
    }
    for(var z=1; z<aMail.length; z++){
        if((aMail[z] - sKey) < 1){
            aResult[z] = (aMail[z] - sKey) + iCharslength;
        } else {
            aResult[z] = aMail[z] - sKey;
        }
    }
    alert(aResult.join(""));
}
fInject('ich-bin-ein-satz', '27')

//-->
</script>
 
Zuletzt bearbeitet:
Ich hab es mal etwas angepasst, weil da anscheinend wirklich ein paar Fehler drin waren. Und wo ich schonmal dabei war, hab ich auch gleich noch mal etwas aufgeräumt.
Code:
<script type="text/javascript">
<!--

function fFind(sSearch){
    for(var x = 0; x < this.length; x++){
        if(this[x] == sSearch){
            var iIndex = x;
            return iIndex;
        }
    }
    return -1;
}

Array.prototype.find = fFind;

function stringToArray(stringValue) {
	stringArray = new Array();
	for(i = 0; i < stringValue.length; i++) {
		stringArray[i + 1] = stringValue.charCodeAt(i) - 96;
	}
	return stringArray;
}

function fInject(sMail, sKey){
	sChars = new String("abcdefghijklmnopqrstuvwxyz");
    aChars = stringToArray(sChars);
    aMail = stringToArray(sMail);
    aResult = new Array();
    var sResult = "";
    iCharslength = sChars.length;

    for(var z = 1; z < aMail.length; z++) {
        if((aMail[z] - sKey) < 1){
            aResult[z] = (aMail[z] - sKey) + iCharslength;
        } else {
            aResult[z] = aMail[z] - sKey;
        }
    }
    
    for(j = 1; j < aResult.length; j++) {
    	aResult[j] = String.fromCharCode(aResult[j] + 96);
    }
    return aResult.join("");
}

alert(fInject("ich-bin-ein-satz", "27"));

//-->
</script>
 
Wenn ich jetzt mal drüberschaue finde ich - bis auf die neue anordnung - nur wenige grundlegende Änderungen.

Da wäre charCodeAt statt charAt. Aber was soll das ' - 96' ? Hat das was mit dem Latin1 Zeichensatz zu tun?
charCodeAt(i) - 96;

Die stringToArray-Funktion erwähne ich mal nicht ;)
Ich wollte mit dem Umschreiben warten, bis ich den Bug gefunden hab :(

Da ich noch am lernen bin, würde ich gerne wissen was ich genau falsch gemacht habe bei meinem Code.

Aber irgendwie kommt bei Deiner Korrektur aber auch nichts besseres heraus :)

Ausgabe: hbg, ahm,dhm,r`sy
 
Ich muss gestehen, ich hab mich als Kind nicht mit Caesar's Code beschäftigt...nur mit unsichtbarer Tinte :)

kannst du mal erläutern, was genau der tut....also was der z.B. aus
'ich-bin-ein-satz'
machen soll...
 
Ich glaub ihr habt nur aneinander vorbeigeredet :). Neuro, du willst den String verschieben, dabei aber nur auf den Zeichen vorrat in sChars zurückgreifen, oder? Dario: Du shiftest den String um den als Parameter übergeben sKey, ohne rücksicht auf sChars? Kann auch sein das ich euch jetzt falsch verstanden habe.

Ich habs mal etwas geändert ;) - vielleicht kommt das näher an das fertige Teil:

PHP:
<script type="text/javascript">
<!--
function fFind(sSearch){
    for(var x = 0; x < this.length; x++){
        if(this[x] == sSearch){
            var iIndex = x;
            return iIndex;
        }
    }
    return -1;
}
Array.prototype.find = fFind;


function stringToArray(stringValue) {
	stringArray = new Array();
	for(i = 0; i < stringValue.length; i++) {
		stringArray[i] = stringValue.charAt(i);
	}
	return stringArray;
}


function fLoop(iOffset){
  if(iOffset>this.length){
    return this[iOffset%this.length];
  }else{
    return this[iOffset];
  }
}
Array.prototype.loop = fLoop;


function fInject(sMail, sKey){
    sChars = new String("abcdefghijklmnopqrstuvwxyz-");
    aChars = stringToArray(sChars);
    aMail = stringToArray(sMail);
    aResult = new Array();
    var sResult = "";
    iCharslength = sChars.length;

    for(var x=0; x<aMail.length; x++){
      aResult[x] = aChars.loop(parseInt(aChars.find(aMail[x]))+parseInt(sKey)); 
    }
    return aResult.join("");    
}

alert(fInject("ich-bin-ein-satz", "10"));
 
Mein Ergebnis:(mit eingebautem Decoder:))
Code:
<script type="text/javascript">
<!--

sChars =String("abcdefghijklmnopqrstuvwxyz-");
function caesar(str,n,decode)
{
while(n>=sChars.length){n-=sChars.length;}
z=decode?-n:n;aChars=new Array();out='';
for(i=0;i<sChars.length;++i)
    {
    x=i+z;
    if(x>=sChars.length){x-=sChars.length;}
    else if(x<0){x+=sChars.length;}
    aChars[sChars.charAt(i)]=x;
    }
for(i=0;i<str.length;++i)
    {
    out+=sChars.charAt(aChars[str.charAt(i)]);
    }
return out;
}
alert(caesar("ich-bin-ein-satz",13,0));

//-->
</script>
....zum dekodieren im Aufruf die 0 durch 1 ersetzen.
 
Ich glaub ihr habt nur aneinander vorbeigeredet . Neuro, du willst den String verschieben, dabei aber nur auf den Zeichen vorrat in sChars zurückgreifen, oder? Dario: Du shiftest den String um den als Parameter übergeben sKey, ohne rücksicht auf sChars? Kann auch sein das ich euch jetzt falsch verstanden habe.
Korrekt! Genau das ist der Sinn der Sache. Ich greife auf den selbst definierbaren Zeichenvorrat.

Ich glaube ich beschreibe das Problem zu ungenau. Es ist super, das Ihr den Code umschreibt und mir andere Möglichkeiten aufzeigt. Irgendwie schiesst das aber am Ziel vorbei. Nehmen wir nochmal meinen Ur-Code - es geht nur um ein Problem - Vereinfachung und höhere Ordnung bringe ich später hinein. Es geht mir nur darum, das ein kleiner Teil sich nicht so verhält, wie ich es erwarten würde.

Original-Code
Code:
<script type="text/javascript">
<!--
function fInit(){
    sChars = new String("abcdefghijklmnopqrstuvwxyz-");
    aChars = new Array();
    for(i = 0; i<sChars.length; i++){
        aChars[i+1] = sChars.charAt(i);
    }
    iCharslength = sChars.length;
    return iCharslength;
}
function fFind(sSearch){
    for(var x=0; x<this.length; x++){
        if(this[x] == sSearch){
            var iIndex = x;
            return iIndex;
        }
    }
    return -1;
}
Array.prototype.find = fFind;
function fInject(sMail, sKey){
    fInit();
    aMail = new Array();
    aResult = new Array();
    var sResult = "";
    for(var y=0; y<sMail.length; y++){
        aMail[y+1] = sMail.charAt(y);
    }
    for(var z=1; z<aMail.length; z++){
        if((aMail[z] - sKey) < 1){
            aResult[z] = (aMail[z] - sKey) + iCharslength;
        } else {
            aResult[z] = aMail[z] - sKey;
        }
    }
    alert(aResult.join(""));
}
fInject('ich-bin-ein-satz', '27')

//-->
</script>

Fehler vermutlich im folgenden Teil:
Code:
    for(var z=1; z<aMail.length; z++){
        if((aMail[z] - sKey) < 1){
            aResult[z] = (aMail[z] - sKey) + iCharslength;
        } else {
            aResult[z] = aMail[z] - sKey;
        }
    }
    alert(aResult.join(""));

Wenn ich alle anderen Teile ausgeben lasse, stimmen die einzelnen Ausgaben. Aber in diesem Teil passiert die eigentliche 'Verschlüsselung'.

Zur Erklärung:
Ich definiere einen Zeichensatz. Den Zeichensatz zestückele ich und weise jedem Zeichen einen numerischen Wert zu (a = 1, b = 2, etc.). Das gleiche muss ich mit dem Input machen. Ich habe also nur noch die numerischen Werte.

Jetzt kann ich mit simpler Addition und Subtraktion die Zeichen verschieben.
Nehmen wir z. B. den String 'abcde'. Die Zahlenwerte sind: '1, 2, 3, 4, 5'. Ich kann die Zeichen nun im von mir definierten numerischen Zeichensatz-'Aphabet' verschieben indem ich den Schlüssel hinzuaddiere oder subtrahiere. Nehmen wir schlüssel '5' und Addition:

a = 1 wird zu a = 6
In unserem Zeichensatz ist 6 = f
Also wird aus a -> f

Der Knackpunkt ist der limitierte Zeichensatz der in meinem Beispiel 27 Zeichen besitzt. Wenn ich also jeden Buchstaben um 27 Zeichen verschiebe, erhalte ich den Originalstring als Ergebnis, damit weiß ich, das mein Script funktioniert. Da 27 der Verschiebung um 0 Zeichen entspricht. Eine Verschiebung um 27 Zeichen KANN nur den gleichen String liefern, eine Verschiebung um 1 hingegen würde jeden Buchstaben um 1 Zeichen verschieben. Ein höherer Wert als 27 wäre unnütz, weil 28 z. B. wieder der 1 entsprechen würde, 29 der 2, usw.

Die Verschiebung des Zeichen 'Z' um fünf Zeichen nach rechts - also eine Addition von 5 - stößt natürlich auf das Problem, das es nur 27 Zeichen gibt. Also rechne ich die Zeichen innerhalb des Strings ab A, bzw. Zeichen 1 dazu. Also: Z + 5 verschiebt das Zeichen von Z +1 zum Zeichen '-' und die restlichen 4 werden ab A dazugerechnet. Bei der Addition ist es das gleiche, nur umgedreht.

----------

Ich möchte doch bloss den Fehler in meinem Code erfahren.

Bei allem Respekt: Ich will gar kein funktionierendes anderes Script, es geht mir doch ums Verstehen meines Fehlers und nicht um ein tolles von wem anderen geschriebenen Script. Wie gesagt, mein Script läuft bis auf die Ausgabe. Ich bekomme keinen Return-Wert. Und bei einer direkten Ausgabe mit alert() erhalte ich NaN statt der einzelnen Zeichen. *sigh*

Ich hoffe das war jetzt nicht ganz so missverständlich :)
 
Zuletzt bearbeitet:
Naja,...was mich betrifft, ich seh bei deinem Code überhaupt nicht durch, was er bezwecken soll.
Nur, weil ein Skript keinen Fehler produziert, würde ich nicht behaupten, dass es läuft.

z.B.macht das hier keinen Sinn, soweit ich sehe:
Code:
function fFind(sSearch){
    for(var x=0; x<this.length; x++){
        if(this[x] == sSearch){
            var iIndex = x;
            return iIndex;
        }
    }
    return -1;
}
Array.prototype.find = fFind;
da du nirgends auf diese Function zugreifst, kanns du sie auch gleich weglassen....das Skript läuft trotzdem wie bisher.

Dann das:
Code:
function fInit(){
    sChars = new String("abcdefghijklmnopqrstuvwxyz-");

    aChars = new Array();
    for(i = 0; i<sChars.length; i++){
        aChars[i+1] = sChars.charAt(i);
    }
    iCharslength = sChars.length;
    return iCharslength;
}
es wird ´sChars´ definiert...OK, dann füllst du ´aChars´....aber wozu, diesen Array verwendest du nirgends. Zurückgegeben wird die Länge von sChars.
Alles in allem hat dies den selben Effekt, als wenn du ´iCharslength´ und ´sChars´ normal als Variablen deklarieren würdest.
Wenn man dies tut, sieht dann alles so aus:
Code:
sChars ="abcdefghijklmnopqrstuvwxyz-";
iCharslength = sChars.length;

function fInject(sMail, sKey)
{
    aMail = new Array();
    aResult = new Array();
    var sResult = "";
    for(var y=0; y<sMail.length; y++)
        {
        aMail[y+1] = sMail.charAt(y);
        }
    for(var z=1; z<aMail.length; z++)
        {
        if((aMail[z] - sKey) < 1)
            {
            aResult[z] = (aMail[z] - sKey) + iCharslength;
            }
       else
            {
            aResult[z] = aMail[z] - sKey;
            }
    }
    alert(aResult.join(""));
}
fInject('ich-bin-ein-satz', '27')
Das Skript macht so genau das selbe wie im Ursprungszustand.

Um die letzte Sache anzugehen....du bekommst keinen Return-Wert, weil die Funktion keinen Return-Wert hat.

Dann gehen wir mal die Funktion durch:
du definierst die Arrays ´aMail´ und ´aResult´...aber wozu ist die Variable ´sResult´ da?
Dann wird der Array ´sMail´ gefüllt:
Code:
for(var y=0; y<sMail.length; y++)
        {
        aMail[y+1] = sMail.charAt(y);
        }
Der hat dann folgenden Inhalt:
aMail[1]='i';
aMail[2]='c';
aMail[3]='h';
aMail[4]='-';
aMail[5]='b';
aMail[6]='i';
aMail[7]='n';
aMail[8]='-';
aMail[9]='e';
aMail[10]='i';
aMail[11]='n';
aMail[12]='-';
aMail[13]='s';
aMail[14]='a';
aMail[15]='t';
aMail[16]='z';

dann wird der Array ´aResult´ gefüllt.
Code:
for(var z=1; z<aMail.length; z++)
    {
        if((aMail[z] - sKey) < 1)
            {
            aResult[z] = (aMail[z] - sKey) + iCharslength;
            }
        else
            {
            aResult[z] = aMail[z] - sKey;
            }
    }
.... da alle Elemente von ´aMail´ nicht numerisch sind, ist das Ergebnis der Berechnungen immer ´NaN´ ....daraus folgt denn im Endeffekt die Ausgabe von einer 'NaN'-Kette.

Man könnte daher das Ganze auf
Code:
<script type="text/javascript">
<!--
function fInject(sMail, sKey)
{
var aResult=new Array();
for(var z=0; z<sMail.length; z++)
    {
    aResult[z] = sMail.charAt(z) - sKey;
    }
    alert(aResult.join(""));
}
fInject('ich-bin-ein-satz', '27');
//-->
</script>
dezimieren.... das ist im Grunde der Teil des Originalskriptes, der überhaupt durchlaufen wird... das Ergebnis ist ebenfalls dasselbe

Ich hoffe, du beisst jetzt nicht in deine Tastatur :)
 
Zuletzt bearbeitet:
Na toll,
dann geht der Script aba immer noch nich.
Ausserdem fehlt jetzt die Abfrage ob der neue Wert im richtigen Bereich ist.
 

Neue Beiträge

Zurück