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 <python-de@python.org> > Betreff: [Python-de] Codepage-Methode und Basis 4096 > Datum: 5. August 2024 um 20:50:35 MESZ > An: python-de@python.org > Antwort an: Wolli Buechel <wjb...@web.de> > > 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 -- python-de@python.org > Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an > python-de-le...@python.org > https://mail.python.org/mailman3/lists/python-de.python.org/ > Mitgliedsadresse: eschn...@multi-matrix.de _______________________________________________ python-de Mailingliste -- python-de@python.org Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an python-de-le...@python.org https://mail.python.org/mailman3/lists/python-de.python.org/ Mitgliedsadresse: arch...@mail-archive.com