Sehr geehrter Herr Büchel,
vielen Dank für Ihre umfangreiche Analyse des
CPM Verfahrens. Zunächst einige Erkärungen vorweg:
Der Codepage-Begriff wird bisher (soweit ich sehe) nur
für Zeichencodierungen höherer <point>Zeichen oberhalb
des ASCII-Bereichs verwendet (z.B: ISO/IEC 8859-1 /www.cscvt.de).
Allerdings besteht der "Code-Bereich" über den ASCII-Bereich hinaus
für alle Zahlensysteme:
Die Unicode-Tabelle insgesamt stellt eine einheitliche Codepage dar. Nach
meinen Erkenntnissen sind für eine Codepage grundsätzlich zwei
Merkmale erforderlich:
„skalierbarer Sachverhalt“
„sachbezogenes Ordnungssystem“
Diese Voraussetzungen sind für das gesamte Unicode-Verfahren erfüllt.
Die Zeichen aller Sprachen sind in einer skalierbaren Reihenfolge <points>
geordnet und werden in einem sachgerechten Ordnungssystem aufgerufen
(Zahlensystem zur Basis 10, 16). Insofern kann das Cpdepage-Verfahren auch
auf allle Unicode-Zeichen angewendet werden.
Ein Beispiel für japanische Schriftzeichen:
select a special part of the whole codepage
1. get part of codepage:
2. get whole codepage:
number > 1
select part from total 0 to 1227
insert begin > 0
insert end > 255
ァ ア ィ イ ゥ ウ ェ エ ォ オ カ ガ キ ギ ク グ ケ ゲ コ ゴ サ ザ シ ジ ス ズ セ
ゼ ソ ゾ タ ダ チ ヂ ッ ツ ヅ テ デ ト ド ナ ニ , ヌ ネ . ノ わ ぬ ふ あ う
え お や ゆ よ ハ バ パ ヒ ビ ピ フ ブ プ ヘ ベ ペ ホ ボ ポ マ ミ ム メ モ ャ ヤ
ュ ユ ョ ヨ ラ リ ル レ ロ ヮ ワ ヰ ヱ ヲ ン ヴ ち こ そ し い は き く に ま
の り も み ら せ た す と か な ひ て さ ん つ じ ず ぜ ぞ だ ぢ っ づ で る れ
ろ ゎ ゐ ゑ を ゔ ゕ ゖ 一 丁 丂 七 丄 丅 乑 丆 万 丈 三 上 下 丌 不 与 丏 丐
丑 丒 专 丨 丩 个 丫 丬 中 丿 乀 乁 乂 乃 乄 久 乆 乇 么 义 乊 之 乌 乍 乞 也 习
乡 乢 乣 乤 乥 书 乧 乨 乩 乪 乫 乬 乭 乮 乯 买 乱 乲 乳 乴 乵 乶 乷 乸 乹 乺
乻 乼 乽 乾 乿 亀 亁 亂 亃 亄 亅 了 亇 予 争 亊 事 二 亍 于 亏 § 亐 云 互 亓 五
井 亖 亗 亘 亙 亚 些 亜 亝 亞 亟 亠 亡 亢 亣 交
marked characters are stored in string >Text<
Dies ist nur eine Auszug. Die gesamte japanische Codepage umfasst einheitlich
1227 Zeichen.
Dazu ist dann das Ordnungssystem zur Basis 4096 erforderlich.
Nun zu Ihren einzelnen Fragen:
Die Ziffern des Zahlenstrings zur Basis 4096 stellen keine Nummerierung von
UTF8-Zeichen dar,
sie liefern nur die jeweilige Position des Zahlzeichens (wie das auch in allen
anderen Zahlenstrings der Fall ist).
Ihre Vermutung, die reduzierten Hausnummern werden anstelle von
Klartextnachrichten übers Netz
verschickt, geht an der Sache vorbei. Es werden hier Nachrichten mit ihren
binären Werten ins Netz geschickt und entsprechend auch wieder aus dem Netz
empfangen.
Zur Frage 3:
Mit der Basis b = 4096 notiert man Zahlen bis 256 mit 1 (einer) Ziffer wie
folgt:
chose mode > D
Basis: 4096
insert dezimal number: 256
256
result: ſ
Das Ergebnis ist das Index-Zahlzeichen “ſ “ mit der Positionsnummer “256”:
Zur Frage 4: 2-ziffrige Zahlzeichen
Welches Zahlensystem braucht man, wenn zum Nummereiren höchstens 2-ziffrige
Zahlziffern
verwendet werden?
Ein Beispiel mit Zahlziffern aus Basis 1056. Alee weitere Beispiele können mit
meinem Programm
“Ziffernsysteme.py” getestet werden.
chose mode > S
Basis: 1056
insert system number: ଷସ
result: 1114079
Zweiziffrige Ergebnisse werden auch noch bei weit höheren Zahlenstrings
erreicht.
Zu allen weiteren Punkten Ihrer Analyse kann ich hier leider keine Stellung
nehmen, da sie nicht Gegenstand meiner Forschung sind (vgl. Vorbemerkungen).
Die Anzahl der Bytes und deren Redcuktion für die jeweiligen Zahlenstrings
spielen in meinen
Ergebinssen keine Rolle (siehe Antwort in den Vorbemerkungen).
Abschließende Bemerkung: "Auch wilde Spekulationen können sinnvolle Ergebnisse
liefern,
wenn die Grundlagen richtig sind". Nur so habe ich ja meine neuen Eerkenntnisse
überhauopt
gewonnen.
Mit freundlichen Grüßen
Erich Schnoor
> Anfang der weitergeleiteten Nachricht:
>
> Von: Wolli Buechel über python-de <[email protected]>
> Betreff: [Python-de] Codepage-Methode und Basis 4096
> Datum: 5. August 2024 um 20:50:35 MESZ
> An: [email protected]
> Antwort an: Wolli Buechel <[email protected]>
>
> Sehr geehrter Herr Schnoor,
>
> hier einige Fragen zu Ihrer Codepage-Methode und dem ominösen Zahlensystem
> zur Basis 4096.
>
> Frage 1
> Warum wählten Sie die Basis b = 4096 für Ihre Codepage-Methode (CPM) zum
> Nummerieren der UTF8-Zeichen?
> Antwort: Da Sie bis jetzt diese Frage nicht beantwortet haben, hier ein
> Antwortversuch von mir.
>
> Frage 2
> Was ist Zweck oder Ziel der CPM? Wozu das Monster-Zahlensystem 4096?
> Antwort: Sie wollen mit CPM den Speicherbedarf (gemessen in 8-Bit-Byte) für
> die dezimalen „Hausnummern“ ord(ch) der UTF8-Zeichen ch reduzieren, und zwar
> auf knapp die Hälfte, durch Verwendung der 4096-Index-Nummern, in die die
> dezimalen Hausnummern übersetzt werden. Die sind gewissermaßen getunte
> Hex-Zahlen (statt der Basis 16 die Superbasis 4096).
>
> Und wozu dieser Aufwand?
> Die byte-reduzierten Hausnummern werden anstelle von Klartextnachrichten
> übers Netz verschickt.
> CPM ist im Kern eine Symmetrische Chiffre mit dem System-Ziffernstring als
> Schlüssel.
>
>
> Frage 3
> (damit man sieht, wo man anfängt, wo’s langgeht, und wo man endet):
> Wie groß muß die Basis b>1 eines Zahlensystems sein, wenn man mit höchstens 2
> Ziffern dieses Systems genau 256 Zahlen (0..255) notieren können will.
> Antwort: b = 16 = Wurzel aus 256, System = Hex-Zahlen
> Denn mit 16 verschiedenen Ziffern kann man 16**2 = 256 ein- oder zweiziffrige
> Hex-Zahlzeichen notieren.
>
> Was einmal geht, geht auch zweimal. Dachten Sie wohl.
> Und ich auch.
>
> Darum hier die zu Frage 3 analoge
>
> Frage 4
> Welche (minimale) System-Basis b>1 braucht man zum Nummerieren der aktuell
> 1.114.111 UTF8-Zeichen, wenn man zum Nummerieren höchstens 2-ziffrige
> Zahlzeichen verwenden will?
> Antwort: b = 1056 = gerundete Wurzel aus 1.114.111.
>
> Überraschung Eins:
> Die Antwort hat mich überrascht: Optimale Basis = wenig größer als ein
> Viertel der Superzahl.
>
> ==============================
> Da Ihre CPM für alle Basiswerte 2 <= b <= 4098 anwendbar ist, habe ich den
> Rechner zur Basis-Testung angeworfen.
> Und die jeweilige Byte-Reduktion ermittelt.
>
> Welchen Ziffernstring habe ich verwendet?
> Den einfachsten: Alle UTF8-Zeichen von 0 bis zur jeweiligen Basis b.
>
> ziffern = ''.join([ chr(x) for x in range(0, 4096) ])
> Anzahl Ziffern : 4096
> Anzahl Bytes : 10112
>
> Dieser Ziffernstring ist optimal, denn der enthält die Zeichen mit den
> wenigsten Byte. Es gibt keinen Ziffernstring mit weniger Byte.
>
> Die Basis läßt sich beliebige verkleinern durch Slicing, z.B.
> basis = 128
> ziffern = ziffern[:basis]
>
> ==========================
>
> Überraschung Zwei:
> Der Test lieferte eine merkwürdiges Ergebnis:
>
> Die größte Byte-Reduktion über alle Codepoints 1 bis 1.114.111 liefert eine
> dreistellige Basis, b = 128.
>
> Hier das Testergebnis für b = 128:
>
> Basis für CPM : 128
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0] # ANZAHL der
> UTF8-Zeichen mit 0,1,2,3,4,5 Byte
> BytesIndex : [0, 128, 16256, 1095680, 0] # ANZAH der Index-Zahlzeichen
> mit 0,1,2,3,4 Byte
> ZiffernIndex : [0, 128, 16256, 1095680, 0] # ANZAH der Index-Zahlzeichen
> mit 0,1,2,3,4 Ziffern
> Σ Bytes UTF8 : 4382592 # Gesamtzahl der Bytes in allen 1.114.111
> UTF8-Zeichen
> Σ Bytes Index : 3319680 # Gesamtzahl der Bytes in allen
> 1.114.111Index-Zahlzeichen
> Diff (I - U) : -1062912 # klar
> Quote (I : U) : 75.75% # klar
> Reduktion : -24.25% # klar
>
> Ergebnis in Worten für b=128:
> ZiffernIndex: Es werden nur 1-, 2- oder 3-ziffrige Zahlzeichen verwendet;
> BytesIndex: Diese Zeichen haben 1, 2, oder 3 Byte.
> Die Anzahl der Zahlzeichen ist gleich der Anzahl der Byte.
> Dies ist vollkommen logisch. Denn die Basis b=128 verwendet in dem
> MINIMALISTISCHEN Ziffernstring exakt 128 Zeichen von einem Byte.
>
> Noch einen Tick besser ist die Byte-Reduktion für b=129:
>
> Basis für CPM : 129
> BytesUTF8 : [0, 127, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 128, 16512, 1095423, 0]
> ZiffernIndex : [0, 128, 16512, 1095423, 0]
> Σ Bytes UTF8 : 4382591
> Σ Bytes Index : 3319421
> Diff (I - U) : -1063170 <== MIN -1.063.170
> Quote (I : U) : 75.74%
>
> ==================================
>
> Und hier der Test für ausgewählte Basis-Werte (b = 2**k, für k= 12, 11, …, 16)
>
> Hinweis:
> Ist ein Reduktionswert POSITIV, handelt es sich tatsächlich nicht um eine
> Reduktion, sondern um einen Mehraufwand.
> Nur NEGATIVE Reduktionswerte bedeuten tatsächlich weniger Aufwand.
> Dies wird auch klar durch Quote (I : U) = Quote (Index : UTF8)
>
>
> Basis für CPM : 4096
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 129, 18432, 266253, 534529, 292721, 0]
> ZiffernIndex : [0, 4096, 1107968, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4437473
> Diff (I - U) : 54881
> Quote (I : U) : 101.25%
> Reduktion : 1.25%
>
> Basis für CPM : 2048
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 129, 18302, 297248, 796385, 0]
> ZiffernIndex : [0, 2048, 1110016, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4114017
> Diff (I - U) : -268575
> Quote (I : U) : 93.87%
> Reduktion : -6.13%
>
> Basis für CPM : 1024
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 129, 17149, 236481, 858305, 0]
> ZiffernIndex : [0, 1024, 1045504, 65536, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4177090
> Diff (I - U) : -205502
> Quote (I : U) : 95.31%
> Reduktion : -4.69%
>
> Basis für CPM : 512
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 129, 16379, 163334, 492155, 440067, 0]
> ZiffernIndex : [0, 512, 259584, 851968, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4691844
> Diff (I - U) : 309252
> Quote (I : U) : 107.06%
> Reduktion : 7.06%
>
> Basis für CPM : 256
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 129, 16639, 297863, 539369, 258064, 0]
> ZiffernIndex : [0, 256, 63232, 1048576, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4374792
> Diff (I - U) : -7800
> Quote (I : U) : 99.82%
> Reduktion : -0.18%
>
> Basis für CPM : 128
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 128, 16256, 1095680, 0]
> ZiffernIndex : [0, 128, 16256, 1095680, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 3319680
> Diff (I - U) : -1062912
> Quote (I : U) : 75.75%
> Reduktion : -24.25%
>
> Basis für CPM : 64
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 64, 4032, 256000, 851968, 0]
> ZiffernIndex : [0, 64, 4032, 256000, 851968, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4184000
> Diff (I - U) : -198592
> Quote (I : U) : 95.47%
> Reduktion : -4.53%
>
> Basis für CPM : 32
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 32, 992, 31744, 1013760, 65536, 0]
> ZiffernIndex : [0, 32, 992, 31744, 1013760, 65536, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 4479968
> Diff (I - U) : 97376
> Quote (I : U) : 102.22%
> Reduktion : 2.22%
>
> Basis für CPM : 16
> BytesUTF8 : [0, 128, 1920, 61440, 1048576, 0]
> BytesIndex : [0, 16, 240, 3840, 59392, 983040, 65536, 0]
> ZiffernIndex : [0, 16, 240, 3840, 59392, 983040, 65536, 0]
> Σ Bytes UTF8 : 4382592
> Σ Bytes Index : 5558000
> Diff (I - U) : 1175408
> Quote (I : U) : 126.82%
> Reduktion : 26.82%
>
> Aber vielleicht sind das alles ja nur wilde Spekulationen?
>
> Wolfgang Büchel
>
> =======================
>
> Das verwendete Python-Programm:
>
> ziffern = ''.join([ chr(x) for x in range(0, 4097) ])
> for k in range(12, 3, -1):
> basis = 2**k
> countBytes_UTF8_CPM(basis, ziffern)
>
> ===============================
>
> def countBytes_UTF8_CPM(basis, ziffern, zeigen=False):
> """
> Ermittelt die Gesamtzahl der 8-Bit-Bytes
> -- aller UTF8-Zeichen <ch> von 1 bis Max_UTF8 = 1.114.111
> -- aller aus <ch> via ord(ch) berechneten Indexzahlzeichen
> für den Ziffernstring <ziffern> der Länge <basis> nach CPM
> (sowie deren Ziffernanzahl)
> und vergleicht diese beiden Byte-Anzahlen.
>
> """
> Max_UTF8 = 1114111
> ziffern = ziffern[:basis] # Ziffernstring für Positionssystem CPM
> basis = len(ziffern) # Basis dieses Positionssystems
> print("\nBasis für CPM : %s" % basis)
>
> # Zähler für die ANZAHL der Bytes ...
> cnt_UTF8 = [0] * 6 # ... in UTF8-Zeichen ch
> cnt_Index_Bytes = [0] * 25 # ... in Index-Zahlzeichen <index>
> # cnt_UTF8[i] = ANZAHL der UTF8-Zeichen mit i
> Byte
> # cnt_Index8[i] = ANZAHL der index-Zeichen mit i
> Byte
> # BytesUTF8 : [0, 127, 1920, 61440, 1048576, 0] bedeutet:
> # UTF8 hat 0 0-Byte-Zeichen,
> # 127 1-Byte-Zeichen,
> # 1920 2-Byte-Zeichen, etc.
>
> # Zähler für die ANZAHL der Ziffern in Index-Zahlzeichen <index>
> cnt_Index_Ziffern = [0] * 25
> # cnt_Index_Ziffern : [0, 1023, 1045504, 65536]
> # bedeutet:
> # Index hat 1023 1-Ziffern-Zahlzeichen
> # 1045504 2-Ziffern-Zahlzeichen
> # 65536 3-Ziffern-Zahlzeichen, etc.
>
> for i in range(1, 1 + Max_UTF8):
> # SKIP 2048 surrogates-Zeichen;
> # in diesem Teilbereich liegen unzulässige UTF8-Zeichen
> if i in range(55296, 1 + 57343): continue
>
> ch = chr(i)
> index = nachsys(basis, i, ziffern)
> numBytesUTF8 = len(bytes(ch, 'utf8'))
> numBytesIndex = len(bytes(index, 'utf8'))
> cnt_UTF8[numBytesUTF8] += 1
> cnt_Index_Bytes[numBytesIndex] += 1
> cnt_Index_Ziffern[len(index)] += 1
>
> if zeigen:
> if numBytesIndex == 3:
> print("[%7d] >%s< >>%s<< " % (i, ch, index))
>
> # Listen-End-Elemente mit Wert 0 abschneiden, ausgenommen das letzte
> while cnt_Index_Bytes[-2] == 0:
> cnt_Index_Bytes = cnt_Index_Bytes[:-1]
> while cnt_Index_Ziffern[-2] == 0:
> cnt_Index_Ziffern = cnt_Index_Ziffern[:-1]
>
> # Summenberechnung für die Gesamtzahl der Bytes cnt_UTF8 und cnt_Index
> sum_BytesU = sum([ i*cnt_UTF8[i] for i in range(len(cnt_UTF8)) ])
> sum_BytesI = sum([ i*cnt_Index_Bytes[i] for i in
> range(len(cnt_Index_Bytes)) ])
> diff = sum_BytesI - sum_BytesU
> quote = 100*sum_BytesI / sum_BytesU
>
> print("BytesUTF8 : %s" % cnt_UTF8)
> print("BytesIndex : %s" % cnt_Index_Bytes)
> print("ZiffernIndex : %s" % cnt_Index_Ziffern)
>
> print("Σ Bytes UTF8 : %7d" % sum_BytesU)
> print("Σ Bytes Index : %7d" % sum_BytesI)
>
> print("Diff (I - U) : %d" % diff)
> print("Quote (I : U) : %0.2f%%" % quote)
> print("Reduktion : %0.2f%%" % (quote-100))
> _______________________________________________
> python-de Mailingliste -- [email protected]
> Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an
> [email protected]
> https://mail.python.org/mailman3/lists/python-de.python.org/
> Mitgliedsadresse: [email protected]
_______________________________________________
python-de Mailingliste -- [email protected]
Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an
[email protected]
https://mail.python.org/mailman3/lists/python-de.python.org/
Mitgliedsadresse: [email protected]