Unicode και κανονικοποίηση κειμένου — DedSec Project
Unicode — αναζήτηση χωρίς αλλοίωση του αρχικού κειμένου Σκοπός Μία δίγλωσση, τοπική βιβλιοθήκη γνώσης εμφανίζει τον αρχικό ελληνικό ή αγγλικό τίτλο και χρησιμοποιεί διαφορετικό κλειδί για…
Unicode — αναζήτηση χωρίς αλλοίωση του αρχικού κειμένου
Σκοπός
Μία δίγλωσση, τοπική βιβλιοθήκη γνώσης εμφανίζει τον αρχικό ελληνικό ή αγγλικό τίτλο και χρησιμοποιεί διαφορετικό κλειδί για αναζήτηση χωρίς διάκριση πεζών και κεφαλαίων. Οπτικά ίδιες λέξεις μπορούν να αποθηκεύονται με διαφορετικές ακολουθίες κωδικών Unicode. Ένα κανονικοποιημένο κλειδί δεν αντικαθιστά τον αρχικό τίτλο, γιατί μπορεί να αντιστοιχεί σε περισσότερες από μία διαφορετικές εγγραφές.
Εκτελέσιμο παράδειγμα Python 3
Αποθήκευσε ως unicode_lab.py και εκτέλεσε python3 unicode_lab.py. Δοκιμάζονται ενιαίοι και συνδυαστικοί τόνοι, παραλλαγές του ελληνικού σίγμα, το τουρκικό İ, ακολουθία emoji με U+200D και άκυρη περικοπή byte UTF-8.
import unicodedata as ud
def search_key(text):
if not isinstance(text, str):
raise TypeError('expected Unicode text')
return ud.normalize('NFC', ud.normalize('NFC', text).casefold())
assert search_key('café') == search_key('cafe\u0301')
assert search_key('Σ') == search_key('ς')
assert search_key('İ') != search_key('i')
assert len('👩\u200d💻') == 3 # three code points, one displayed emoji
raw = 'έ'.encode('utf-8')
try:
raw[:1].decode('utf-8')
except UnicodeDecodeError:
pass
else:
raise AssertionError('partial UTF-8 decoded unexpectedly')
assert ud.normalize('NFD', 'έ') != 'έ'
print('PASS unicode: NFC, casefold, UTF-8 boundary')
Τι δείχνουν οι έλεγχοι
Το ορατό γράμμα é μπορεί να αναπαρίσταται με έναν ενιαίο κωδικό ή με e και ξεχωριστό τόνο. Η NFC μετατρέπει κανονικά ισοδύναμες ακολουθίες σε κοινή μορφή, ενώ η NFD διαχωρίζει πολλούς τονισμένους χαρακτήρες. Η casefold βοηθά στη σύγκριση, αλλά δεν είναι αντιστρέψιμη: το κεφαλαίο Σ και το τελικό ς μπορούν να γίνουν ίδιο κλειδί. Το τουρκικό κεφαλαίο İ δεν είναι ίδιο με το απλό λατινικό i στην κοινή μετατροπή Unicode. Η len της Python μετρά σημεία κώδικα, όχι πάντοτε ορατούς χαρακτήρες. Ένα emoji επαγγελματία με σύνδεσμο U+200D μπορεί να εμφανίζεται ως ένα σύμβολο και να αποτελείται από τρεις κωδικούς. Η UTF-8 χρησιμοποιεί μεταβλητό αριθμό byte, άρα αυθαίρετη περικοπή μπορεί να δημιουργήσει άκυρο κείμενο.
Συγκεκριμένες ασκήσεις
- Εμφάνισε repr και τα ονόματα των κωδικών Unicode για café και την αποσυντεθειμένη γραφή του. Φύλαξε και τις δύο αρχικές μορφές.
- Βάλε Σ και ς σε δοκιμαστικό ευρετήριο. Αν τα κλειδιά συμπίπτουν, η αναζήτηση πρέπει να εμφανίζει και τους δύο τίτλους, όχι να χάνει τον έναν.
- Σύγκρινε ελληνικό τίτλο με τόνο και παραπλανητικά όμοιο κείμενο άλλου αλφαβήτου. Η κανονικοποίηση δεν είναι μεταγραφή ή πλήρης έλεγχος ασφαλείας.
- Κόψε ελληνικό UTF-8 μετά το πρώτο byte και κατάγραψε UnicodeDecodeError. Η περικοπή ανά κωδικό δεν ισοδυναμεί πάντα με περικοπή ανά ορατό γράφημα.
Παραδοτέα: PASS, λίστες κωδικών, μία σύγκρουση κλειδιών αναζήτησης και αναπαραγωγή σφάλματος αποκωδικοποίησης.
Πρόσθετη τεχνική ανάλυση
Τα όρια κωδικοποίησης προηγούνται κανονικοποίησης. Ένα τμήμα bytes μπορεί να τελειώνει μέσα σε χαρακτήρα UTF-8· αποκωδικοποίησε σταδιακά και ολοκλήρωσε τον decoder στο πραγματικό τέλος. Έπειτα κανονικοποίησε και ανάλυσε εγγραφές, επειδή πρόωροι χαρακτήρες αντικατάστασης αλλοιώνουν αναγνωριστικά και συγκρίσεις.