Πέμπτη, 22 Φεβρουαρίου 2018

Χρήση Διάρθρωσης για κείμενο 8bit και μετατροπές κωδικοσελίδας

Το παρακάτω πρόγραμμα το γράφουμε σε ένα τμήμα έστω Α (με Σ Α + enter και μετά επικόλληση και πατάμε Esc) και μετά το τρέχουμε.
Τι κάνει;
Φτιάχνει μια διάρθρωση μνήμης με bytes (ψηφία) και βάζει από το 32(33ή θέση) έως το 255 όλα τα νούμερα από 32 έως 255. Υποθέτουμε ότι αυτοί είναι χαρακτήρες σε Ρώσικα 8 Bit  σε κωδικοσελίδα 1049. Πραγματικά δεν ξέρουμε τι είναι αν δε μας πουν τι είναι!
Υπάρχει τρόπος να διαβάσουμε το αλφαριθμητικό από την διάρθρωση δίνοντας τη θέση του πρώτου ψηφίου και τον αριθμό των ψηφίων που θα διαβαστεί, στην συνάρτηση Εκφρ$(). Αυτή η συνάρτηση παίρνει ότι του δίνουμε και τα γράφει σε ένα αλφαριθμητικό χωρίς καμία μετατροπή. Το αλφαριθμητικό όμως αν διαβαστεί έτσι θα βγει λάθος γιατί κανονικά διαβάζεται ως UTF16LE ενώ εμείς του έχουμε βάλει ASCII (ή πιο σωστά ANSI το οποίο όμως δεν το έχουμε μετατρέψει). Πράγματι αν διαβάσουμε το μήκος του Α$ θα μας δώσει 112 ενώ οι χαρακτήρες που έχουμε βάλει στην Διάρθρωση είναι 225 (τα 32 πρώτα δεν τα χρησιμοποιούμε)
Παραβλέπουμε για την ώρα μια επιπλέον μετατροπή αν η Ansi κωδικοσελίδα στο σύστημα δεν είναι η ελληνική (το βρίσκουμε βλέποντας αν το Γ είναι το 195).
Η  Χαρ$(αλφαριθμητική παράσταση) κάνει μετατροπή και ανοίγει τους χαρακτήρες από εκεί που ήταν δυο σε μια θέση τους κάνει ένα σε κάθε θέση των δυο ψηφίων (bytes). Γράφουμε το Β$ και τώρα το μήκος του είναι 224, όπως πρέπει δηλαδή.
Δείχνουμε ότι μπορούμε να βλέπουμε το Β$  με διαφορετική κωδικοσελίδα, με λατινικά και με ρώσικα. Επιλέγουμε τα ρώσικα και το Α$ έχει τώρα ρώσικα. Δηλαδή τελικά από την Διάρθρωση διαβάσαμε ρώσικα των 8bit ANSI σε αλφαριθμητικό που τώρα είναι σε UTF16LE.
Τώρα θα κάνουμε το ανάποδο, θα πάρουμε αυτούς τους 224 χαρακτήρες των δύο ψηφίων ο καθένας και θα τους κάνουμε 224 του ενός ψηφίου το καθένα. Και θα βάλουμε αυτούς τους χαρακτήρες στην διάρθρωση και θα κάνουμε έλεχγο αν τα νούμερα είναι όπως πρέπει πχ στη θέση 100 θα είναι το 100, στη θέση 150 το 150. Ήδη έχουμε μηδενίσει την μνήμη με εγγραφή σε όλες τις θέσεις του 0.
Πάλι αφήνουμε την μετατροπή που χρειάζεται αν το σύστημα δεν είναι Ελληνικό (για μη unicode συστήματα).
Μας ενδιαφέρει να γυρίσουν τα νούμερα στα κανονικά (αλλά σε Utf16le) και όταν θα τα προβάλει η Τύπωσε θα βγουν Ελληνικά.
Βάζουμε το αλφαριθμητικό στη διάρθρωση και αυτό γίνεται με αντιγραφή των ψηφίων (bytes), χωρίς μετατροπή.
Τώρα ελέγχουμε σαρώνοντας την διάρθρωση, και αν υπάρχει λάθος θα βγεί λάθος και θα σταματήσει το πρόγραμμα.

Για τους υπολογιστές με λειτουργικό που δεν είναι στα ελληνικά έχουμε κάνει ήδη στο κώδικα τα απαιτούμενα:
1. Να βάλουμε το Τοπικό 0 που σημαίνει ότι σίγουρα θα διαβάζει τη στάνταρ κωδικοσελίδα (που δεν ξέρουμε ποια είναι, αλλά σίγουρα δεν είναι η ελληνική γιατί το Κωδ("Γ") δεν βγαίνει 195 όπως το βρίσκουμε παρακάτω). Δουλεύει και με Τοπικό 1032.
2. Αν δούμε ότι όντως δεν έχουμε ελληνική στανταρ σελίδα κάνουμε μια μετατροπή στη στανταρ με το 0. Αυτό συμβαίνει γιατί το άνοιγμα από ένα σε δυο ψηφία έγινε στα ελληνικά(έτσι έχει επιλεχθεί στη γλώσσα για να υπάρχει κάτι στανταρ).
3. Πάλι χρειάζεται στην ανάποδη μετατροπή μια διαφοροποίηση στη μέθοδο.

Το πρόγραμμα έχει ελεχθεί σε Window XP και 7 σε 32bit, και σε Windows 8 και 10 σε 64bit (με επιλεγμένη γλώσσα για μη Unicode τα αγγλικά), καθώς και σε Wine 1.8 (Ubuntu) (με υποστήριξη ελληνικών στα μη Unicode - εδώ δεν ξέρω και πώς αλλάζει αυτό, αλλά προφανώς το πήρε επειδή η γλώσσα του Ubuntu ειναι τα ελληνικά).



Τοπικό 0
Διάρθρωση Ascii ως ψηφίο*256
Για Ι=32 έως 255
      Επιστροφή Ascii, Ι:=Ι
Επόμενο Ι
Α$=Εκφρ$(Ascii, 32, 224)
Για Ι=32 έως 255
      Επιστροφή Ascii, Ι:=0
Επόμενο Ι
Τύπωσε Μήκος(Α$) ' 112  ' κάθε χαρακτήρας έχει δυο χαρακτήρες
Β$=Χαρ$(Α$) ' τώρα διπλασιάσαμε το μήκος και κάθε χαρακτήρας έχει έναν χαρακτήρα
' εδώ θα γίνει πάντα στα ελληνικά (επειδή έτσι κάνει ο διερμηνευτής και αυτό δεν αλλάζει)
Τύπωσε Μήκος(Β$) ' 224
Τύπωσε Β$ ' εμφανίζεται με την στανταρ κωδικοσελίδα
\\ ελέγχουμε αν είναι όντως ελληνικό το σύστημα για μη unicode
\\ αν δεν είναι δεν βγαίνει το Γ ως 195, και τότε κάνουμε μια μετατροπή ακόμα
Αν Κωδ("Γ")<>195 Τότε Β$=Γραφή$(Β$,0)
\\ μετατρέπουμε τους κωδικούς Ascii σε Unicode βάσει κωδικοσελίδας
Τύπωσε Χαρ$(Β$, 1033) ' εμφανίζεται με την 1033 (λατινικά με τόνους)
Τύπωσε Χαρ$(Β$, 1049) ' εμφανίζεται με ρώσικα.
\\ καθαρίζουμε την μνήμη
Α$=Χαρ$(Β$, 1049) ' τώρα το Α$ έχει 224 χαρακτήρες unicode ρώσικους!
Β$=Γραφή$(Α$, 1049) ' μετατρέπουμε από την 1049 στην 1033
\\ πάλι ελέγχουμε το Γ και αν δεν είναι 195 κάνουμε μετατροπή στα ελληνικά
Αν Κωδ("Γ")<>195 Τότε {
      Β$=Χαρ$(Β$, 1032)
} Αλλιώς Β$=Χαρ$(Β$, 0) ' τώρα γυρνάει στο κανονικό (θέλουμε ελληνικά)
\\ όπως και να έχει θα πάρουμε ελληνική κωδικοσελίδα εδώ
\\ τώρα μπορούμε να τα βάλουμε στη διάθρωση.
Τύπωσε Β$
Τύπωσε Μήκος(Β$) ' 224
Β$=Γραφη$(Β$)
Τύπωσε Μήκος(Β$) ' 112 τώρα βάλαμε δυο χαρακτήρες σε κάθε έναν
Επιστροφή Ascii, 32:=Β$ ' Βάζουμε πίσω στη μνήμη τα ψηφία
Για ι=32 έως 255
      Αν Εκφρ(Ascii, ι)<>ι τότε Λάθος "έκανες λάθος"
Επόμενο ι
Τύπωσε
Τύπωσε Α$