• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Codepoint von Charakter ?

wolf360

Neues Mitglied
Hallo, wie bekomme ich den Codepoint von einem char? Ich habe eine binäre Zeichenkätte und würde sie geren zurück in ein Charakter wandeln, aber da kommt nur Müll raus:
PHP:
 $cryptString = chr(bindec(strrev($newchar)));  echo $cryptString;
Wenn ich das so mache bekomme ich: � ausgegebn, aber eigentlich müsste das ¿ sein... Was mache ich falsch ? grüße wolf360
 
Kann auch garnicht funktionieren, chr erwartet einen Wert von 0 bis 255 und gibt einen ASCII-Wert zurück - das "¿" ist allerdings kein ASCII-Zeichen, sondern in Unicode enthalten.



Was genau möchtest du denn mit deinem Code erreichen? Also was sollen $newChar und $cryptString sein?
 
Ist für ein Schulprojekt, wir sollen eine Verschlüsselung Programmieren und dafür brauch ich das. Geht das irgendwie anders ?
 
Das kommt ganz drauf an, was für eine Verschlüsselung du implementieren willst. Solltet ihr euch ein Verfahren selber ausdenken oder ein schon bekanntes implementieren? Wie sehen deine bisherigen Gedanken dazu aus?
 
Wir sollten uns selbst eins Ausdenken und Subsitution, Permutation und Expansion anwenden. Die Substitution wäre halt das umdrehen des Binärwerts gewesen. Das Projekt wurde schon abgesegnet und muss jetzt nur noch umgesetzt werden, hat bis jetzt auch ganz gut geklappt >.
 
Zuletzt bearbeitet:
Dann hast du Funktionen verwendet, welche nur auf ASCII-Zeichen anwendbar sind.



Kurze Erklärung:
Die am meisten verwendeten Zeichen wurden zu einer Art Sammlung zusammengefasst, die ASCII-Zeichen. Diese umfassen einige Steuerzeichen, Sonderzeichen, Zahlen und Buchstaben. ASCII-Zeichen haben eine Länge von 7 Bit, die entsprechende Tabelle sieht so aus:
American Standard Code for Information Interchange

Umlaute etc. kann man damit noch nicht darstellen, deswegen gibt es erweiterte Zeichentabellen. Die verbreitetste dieser "kleinen" Tabellen ist ISO-8859-1 und besteht aus 8 Bit pro Zeichen:
ISO/IEC 8859-1 - Wikipedia, the free encyclopedia

Allerdings sind auch hier viele Zeichen nicht enthalten, weswegen man eine weitere Tabelle mit Zeichen erstellt hat: Unicode. Hier sind eine riesige Menge an Zeichen enthalten, dafür ist die Unicode-Tabelle auch entsprechend riesig:
Liste der Unicode-Blöcke

Der Großteil der Buchstaben in einem Text besteht jedoch noch immer aus Den Zeichen, welche in ISO-8859-1 enthalten sind. Um nicht unnötig Platz zu verschwenden, wird meist zur Benutzung von Unicode UTF-8 verwendet:
UTF-8



Ließ dir mal die Artikel dazu durch und inbesondere den zu UTF-8, dann weißt du wie solche Zahlen intern abgespeichert werden und wieso gewisse Mehoden nicht funktionieren.




In meiner Erklärung ist sicherlich die ein oder andere Ungenauigkeit enthalten, aber das ist der Aufbau soweit ich ihn verstanden habe - ich denke das sollte auch reichen um dieses Problem im Angriff zu nehmen.
 
Liest sich gut. :)

wolf360, beschreib das mal bitte alles etwas genauer (den Algorithmus, mögliche Ein- und Ausgaben mitsamt eingesetztem Charset). Es kann gut sein, dass das Problem woanders liegt (etwa falsches Charset/Encoding in Ein- bzw. Ausgabe -- zum Beispiel UTF-8 statt ISO-8859-1). Wenn der Algorithmus Binärdaten byteweise 1:1 packen und entpacken kann, dürfte das Encoding für den Algorithmus erstmal irrelevant sein.
 
hier mal mein code
Code:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
PHP:
$cryptString = null; 
    $textArray = str_split($this->text); 
    $keyArray = str_split($this->key); 
    $keyLength = count($keyArray); 
    $counter = 0; 

    /* Zeichen Oder verküpfen (Permutation)*/ 
    $cryptArray = array(); 
    foreach($textArray as $char) { 
      $cryptArray[] = $this->xOder($char, $keyArray[$counter]); 
        if ($counter == $keyLength) { 
            $counter = 0; 
        } else { 
            $counter++; 
        } 
    } 

    /* Substitution */
    foreach($cryptArray as $char) {
    switch(strlen(decbin(ord($char)))) 
    {
        case 7: $char = "0".decbin(ord($char));
          break;
        case 6: $char = "00".decbin(ord($char));
          break;
        case 5: $char = "000".decbin(ord($char));
        break;
        case 8: $char = decbin(ord($char));
    }

    $blocks = array();
    $blocks[] = substr($char, 0,2); 
    $blocks[] = substr($char, 2,2); 
    $blocks[] = substr($char, 4,2); 
    $blocks[] = substr($char, 6,2); 
    
    $newchar = null;  
    foreach($blocks as $block) { 
        switch($block)  
        { 
            case '00': $newchar .= '10'; 
            break; 
            case '01': $newchar .= '11'; 
            break; 
            case '10': $newchar .= '00'; 
            break; 
            case '11': $newchar .= '01'; 
            break; 
        }
         
    }
    echo bindec(strrev($newchar))."<br>";  
    $cryptString .= chr(bindec(strrev($newchar))); 
    exit; 
    } 
    echo $newchar;  
    return $cryptString;
 
Zuletzt bearbeitet:
Das ganze sollte Byteweise interpretiert werden und damit kein Problem darstellen. Bis auf eine Stelle:
PHP:
    switch(strlen(decbin(ord($char)))) 
    {
        case 7: $char = "0".decbin(ord($char));
          break;
        case 6: $char = "00".decbin(ord($char));
          break;
        case 5: $char = "000".decbin(ord($char));
        break;
        case 8: $char = decbin(ord($char));
    }

Es kann bei Nicht-ASCII-Zeichen [und auch bei ASCII-Steuerzeichen] passieren, dass die "binäre Länge" kleiner ist als 5. Benutz besser die Funktion [phpnet]str_repeat[/phpnet]


Sollte damit der Fehler nicht behoben sein, weiß ich auch nicht woran das liegen kann.
 
Also bei dem testbeispiel warn alles 8 bit das Problem ist doch das bei der Umwandlung dezimal 192 raus kommt und die ASCII Tabelle nur bis 127 geht oder nicht?
 
Hier bin ich leider ein wenig überfragt, wie die Ausgabe von ord() dann aussieht. Probier einfach mal aus was z.B. ord("Ä") ausgibt - wenn der Wert größer ist als 127, dann sollte alles klappen. Wenn nicht, dann müsste man sich einen anderen Weg ausdenken, einen Buchstaben in die Binärdarstellung zu überführen.



Das ginge mit bitweisen Operatoren, allerdings weiß ich nicht ob man die in PHP auf Stings anwenden kann.



Edit: Hab Jetzt PHP bei mir installiert, es funktioniert tatsächlich nicht so wie erwartet. Bei Zeichen wie ÄÖÜäöü etc. lautet die Ausgabe von ord() immer 195 - hier bin ich leider komplett überfragt.
 
Zuletzt bearbeitet von einem Moderator:
ord() gibt bei Multibyte-Characters den Wert des ersten Bytes zurück. Bei ÄÖÜ (in UTF-8) beträgt der (zufällig) immer 195.

Denke, das hier wird erstmal weiterhelfen:

PHP:
<?php // Datei gespeichert als UTF-8

mb_internal_encoding('UTF-8');
header('Content-Type: text/plain; charset=UTF-8');

$input    = 'ÄÖÜäöü߀ abc 123';
$inputLen = mb_strlen($input);

for ($i = 0; $i < $inputLen; $i++) {
    $utf8Char = mb_substr($input, $i, 1);
    
    $bytes = str_split($utf8Char);
    
    echo $utf8Char . "\t";

    foreach ($bytes as $byte) {
        echo sprintf('%08b ', ord($byte));
    }

    echo "\n";
}

Ausgabe:

Code:
Ä	11000011 10000100 
Ö	11000011 10010110 
Ü	11000011 10011100 
ä	11000011 10100100 
ö	11000011 10110110 
ü	11000011 10111100 
ß	11000011 10011111 
€	11100010 10000010 10101100 
 	00100000 
a	01100001 
b	01100010 
c	01100011 
 	00100000 
1	00110001 
2	00110010 
3	00110011
 
ich würde sagen, du machst das gans ungefähr so(wilst selbst mahl so machen, hab blos grad kein Bock das zu Programmieren). Also
du hast z.B. nur Binäre daten
sop jetzt list du den Wert aus von so einem Zeichen(wie bei Askii). diese machst du dann immer in 255 schreibst du dann das zeichen. und ziehst es von dem Wert des Zeichen ab.
Beispiel:
du hast 700 raus bekommen(die zuhortnungszahl des Zeichen) jetzt schreibst du 2 mahl das zeichen 255, 255(insgesamt 510) und ziehst es von den 700ab. also hast du noch 190. Das Askizeichen gibst und deshlb schreibst du es dann auch. Also jetzt hast du 255, 255, 190.

Weiter: möchtest du es dann wieder entpackschlüsseln machst du das so, dass du solange alle 255 zusammen zählst, dass bist ein niedriger Wert kommt. Dann schreibst du das zeichen.
Beispiel:
wir haben jezt 255, 255, 190 und wir möchten das Zeichen wieder haben so machst du das so. du list das erste zeichen(255) und schaust ob es 255 ist? Wenn Nein schreibst du das zeichen, wenn ja dann mache weiter und speicher den Wert. Jetzt schaust du ob das 2 Zeichen(255) ist. Wenn nein adierst du die Summer der beiden Werte und schreibst die Summe dann als Zeichen, wenn ja dann machst du weiter und adierst den Wert hinzu zu den ersten 255. Nun gehest du zum 3 Zeichen(190) und schaust du ob es 255 ist. Wenn nein(denke mahl dass du es geschrieben hast) addierst du die 190 mit den 510 und schreibst das Zeichen. und dann fängst du wieder von vorne an.
Wichtig: Dieses Verfahren hab ich mir kurz ausgedacht also keine Garantie darauf.

Weiter: wass ist wenn einmahl das zeichen 510 kommt? gans einfach ein 0 Zeichen setzten für das System, damit es weißt, dass hier das Zeichen endet
Wieso so(Beispiel):
du hast 255,255,0,255,255,190.
nun möchtest du es entschlpüsseln.
du gehst von 255, 255 ,0. Bei 0 siehst du, dass das Zeichen endet, weil der wert kleiner ist als 255. Du fängst dann als nächtes ein neues Zeichen an.
würdest du aber 255,255,255,255,190 schreiben, würest du auf einen Fehler stoßen. dein Programm weiß nicht, dass zwischen 2. 3. ein Neues Zeichen anfägt. es würde alles zusammenzäheln bist 190 und du hättest dann ein falsche Zeichen, also PASS AUF SOWAS AUF!!!
 
Die Idee und Darstellung in allen Ehren, aber was du beschreibst, ist im Grunde lediglich ein mit UTF-8 vergleichbarer Weg, Zeichen zu kodieren. Sieh dir mal bei Wikipedia an, wie Zeichen in UTF-8 kodiert werden (Link steht weiter oben im Thread).

Im Grunde ist's nur wichtig, alle Operation strikt byteweise auszuführen. Simples Beispiel:

PHP:
<?php // Datei als UTF-8 gespeichert

class Crypto
{
    /**
     *
     * @param string $data
     * @param string $key
     * @return string
     */
    public function encrypt($data, $key)
    {
        $bytes = str_split($data);
        $res   = '';

        $i = 0;
        $keyLength = strlen($key);
        foreach ($bytes as $byte) {
            $res .= $byte ^ $key[$i % $keyLength];
            $i++;
        }

        return $res;
    }

    /**
     *
     * @param string $data
     * @param string $key
     * @return string
     */
    public function decrypt($data, $key)
    {
        $bytes = str_split($data);
        $res   = '';
        
        $i = 0;
        $keyLength = strlen($key);
        foreach ($bytes as $byte) {
            $res .= $byte ^ $key[$i % $keyLength];
            $i++;
        }

        return $res;
    }

    /**
     *
     * @param string $data
     * @return string
     */
    public function getBinaryRepresentation($data)
    {
        $bytes = str_split($data);
        $res   = '';

        foreach ($bytes as $byte) {
            $res .= sprintf('%08b ', ord($byte));
        }

        return trim($res);
    }

    /**
     *
     * @param string $data
     * @return string
     */
    public function getHexRepresentation($data)
    {
        $bytes = str_split($data);
        $res   = '';

        foreach ($bytes as $byte) {
            $res .= sprintf('%02X ', ord($byte));
        }

        return trim($res);
    }
}

header('Content-Type: text/html; charset=UTF-8');

$c = new Crypto();

$data = 'ÄÖÜ߀ abc 123';
$key  = '9]!X/Ü';

$encrypted = $c->encrypt($data, $key);
$decrypted = $c->decrypt($encrypted, $key);

echo '<table style="font-family: monospace;" border="1">';
printf("<tr><td>Original</td><td>%s</td><td>%s</td></tr>", $data, $c->getHexRepresentation($data));
printf("<tr><td>Encrypted</td><td>%s</td><td>%s</td></tr>", $encrypted, $c->getHexRepresentation($encrypted));
printf("<tr><td>Decrypted</td><td>%s</td><td>%s</td></tr>", $decrypted, $c->getHexRepresentation($decrypted));
echo '</table>';

Edit: Sowas ist relativ leicht zu knacken: Polyalphabetische Substitution
 
Zuletzt bearbeitet:
okey hab einen leichteren weg für die Sonderzeichen gefunden und auch dir Wirkliche ursache,

die Sonderzeichen werden blos anders Dargestellt weil der Browser sie nicht darstellen kann, man bräuchte dafür den html-Code des jeweiligen Sonderzeichens.

aber ich habe eine Andere frage, da ich einen Fehler festegestllt habe:

Wie mach ich es in PHP das ich 2-Char variablen XOR Verknüpfe ?

weil $var1 |= $var2 macht nur ein OR-Verknüpfung, deswegen würde die Rückwandlunge eh nie funkionieren

grüße

wolf360
 
In meinem Beispiel habe ich das übrigens implementiert.

Edit:

Code:
$res .= $byte ^ $key[$i % $keyLength];
 
Zuletzt bearbeitet:
Zurück
Oben