מתיאוריה למציאות, או עד כמה UTF-16 באמת בעייתי

ב־8.9.2008, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, Unicode; ‏7 תגובות

בהמשך לפוסט הקודם, החלטתי לעשות סקירה קצרה: "האם באמת תכנות שכתובות עם utf-16 לא עובדות כמו שצריך עם קידודים כפולים ומה קורה עם תכנות שמשתמשות בייצוג פנימי ב־utf-8/utf-32?"

לקחתי תו "𠂊" או U+2008A וניסיתי להציג אותו ביישומים שונים מבוססים על toolkitים שונים. התו הזה מתייחס ל־CJK Unified Ideographs Extension B‏ ולא לא יכול להיות מיוצג ב־utf-16 בעזרת איבר אחד (שני בתים) אלא דורש צירוף של שני איברים (ארבעה בתים). אם אתם לא רואים את התו הזה, או רואים אותו כריבוע בדפדפן שלכם, אפשר להתקין גופן חופשי: AR PL ShanHeiSun Uni, בעלי דביאן יכולים להתקין חבילה ttf-arphic-uming.‏ חייב לציין, אין מי מושג מה התו או המילה האלה אומרים, כך שמתנצל מראש.

קודם כל: היישומים שעובדים עם utf-16 שהתמודדו אתו בצורה יפה ונכונה (או פשוט לא מצאתי באגים ב־2 דקות ששיחקתי איתם) הם:

  • OpenOffice שעובד עם icu (אם כי, אני לא בטוח שהוא משתמש בו בייצוג פנימי)
  • Microsoft Word עבד ללא בעיות ועובד עם Windows API המבוסס על utf16‏.
  • FreeMind שכתוב ב־Java הצליח להציג את התו ולערוך טקסט בצורה מסודרת. (Java משתמשת ב־utf-16 במחרוזות שלה).

אבל פה פחות או יותר נגמרו היישומים שעובדים עם utf-16 וגם מסתדרים עם התו הבעייתי. נתחיל:

  • יישומי לינוקס המבוססים על QT שמשתמש ב־utf16 ב־QString:‏ KEdit, KWrite, Konqueror, KWord, KolorPaint פשוט לא עבדו! כולם מציגים שני ריבועים שניתן לערוך בנפרד במקום תו (או לפחות ריבוע) אחד! כנ"ל כל הדיאלוגים, כמו שמירת קובץ, לא עובדים.
  • Opera שגם עובדת עם QT אומנם מציגה תווים אבל מחיקה של תו דורש שתי לחיצות על מקש שמאמצע המחיקה מתקבל זבל.
  • יישומי Win32 הבסיסיים כמו Notepad מציגים את התו אבל המחיקה דורשת שתי לחיצות, ושוב באמצע יש זבל. גם במנהל הקבצים של Windows העריכה משובשת ודורשת מחיקות כפולות

עכשיו נסתכל ביישומים שעובדים עם utf-8/utf-32:‏

  • xterm/mlterm אומנם לא הציגו את הגופן אבל היה ברור בפירוש שהם רואים תו בודד.
  • יישומי GTK עבדו ללא דופי, גם הציגו תווים גם העריכה הייתה נכונה, GIMP צייר את התו בצורה יפה מאוד בניגוד ל־KolorPaint. אפשר היה לערוך שמות של קבצים ב־Nautilus שהכילו את התו ובכלל לא מצאתי בעיות מיוחדות (גם ב־Gimp על Windows)‏.
  • מעבד תמלילים Anjuta (שגם הוא מבוסס על GTK ו־Pango) עבד ללא בעיות נראות לעין.

מסקנה: אל תשתמשו ב־utf-16 אם אכפת לכם שהתכנה תעבוד כראוי!

מה שהדהים אותי בבדיקה הפשוטה הזו, היא הקלות בה מצאתי את הבאגים האלה ברכיבים מאוד בסיסיים של כלים שקיימים שנים רבות ואמורים להיות בדוקים היטב. מה שברור לי, ש־utf-16 היא מעין פצצה מתקתקת שאתה לא יודע מתי ואיפה היא תתפוצץ. כך שתעשו לעצמכם טובה ותחשבו טוב--טוב, לפני בחירת ה־toolkit הבא שעובד עם הקידוד המוזר הזה.

תגובות

ik_5, ב־8.9.2008, 12:27

אני לא מקבל את המסקנה שלך. כשאני התחלתי לפני כמה שנים לכתוב כלים לעבוד עם יוניקוד, אחד הדברים שהשקעתי בהם המון מחשבה וזמן היו למצוא את האורך של תו בודד (כאמור בין בית אחד ל4 בתים וכו') וכאשר אני מציין אורך, לציין אותו בתור תו בודד, וכאשר אני מעתיק, אז אני מעתיק סתם לדוגמא מ"בית 1 לבית 2" שזה יכול להיות בפועל 8 בתים כולל במחיקה של תווים.

אני חושב שלא הרבה מושקע ב UTF-16 (אני מקווה שהעבודה שנעשת כרגע על FPC בנושא תניב פירות טובים בנושא).

בכל מקרה, מה שאני גיליתי בדרך הקשה היא, שאם לך יש צורך מסויים (לפחות בקוד הפתוח), אז אתה הבן אדם המתאים לעשות אותו. רוב הספריות והעבודה בכלל בד"כ נעשית ע"י אנשים דוברי לטינית, אשר להם במקרה הרע יש צורך בתמיכה ל256 תווים כאשר הם עורכים טקסט "רגיל". ובגלל זה הדברים נראים ככה.

ארתיום, ב־8.9.2008, 12:46

אני לא בטוח, אבל אני חושב שהבנת אותי --- אין לי בעיה עם utf-8 בהם תו יכול להיות בין 1 ל־4 בתים.

תשים לב, שכאשר אתה עובד עם utf-8 אין לך ברירה אלא תמיד לחשוב במושגים של תווים באורך שונה, שם אפילו שפות מערביות כמו צרפתית/ספרדית דורשות התייחסות לאורך משתנה כי מחצית התווים הם באורך 2. כך שכל מפתח משקיע הרבה כדי לעשות הפרדה בין תווים באלה.

לעומת זאת אם אתה עובד עם utf-32 אז שם יש לך תמיד התאמה אחד לאחד של תו ואיבר במחרוזת. כי כל איבר יכול להכיל תו בודד. כך אפשר ופשוט יחסית לעבוד (אם כי זה לא תואם ל־C Strings) --- למעשה זה הקידוד הפנימי בו אני עובד ב־biditex.

כשמדובר ב־utf-16 ב־99% מהמקרים אתה בכלל לא צריך לחשוב על הפרדה בין תווים כי כמעט כל תו תואם תו בודד של utf-16 למעט תווים נדירים כמו u+2008a שלא נכנסים ל־16 ביט. ופה בדיוק יש בעיה, כי רוב המתכנתים שעובדים עם utf-16 שוכחים מהעובדה הזו כי ברוב רובן של השפות אתה יכול להניח התאמה בין תו לאיבר. פה בדיוק באים הבאגים.

אני מסכים שצריך לעשות הרבה מחשבה, אבל אתה צריך לבחור בין קידוד בעל אורך משתנה (כמעט תמיד) utf8 בין קידוד בעל אורך קבוע utf-32. אם אתה בוחר בקידוד בעל אורך "כעט" קבוע utf-16 אתה נופל, מה שהראיתי בדוגמאות הרבות.

elcuco, ב־8.9.2008, 19:12

היישומים שבדקת הם מבוססים Qt3. אתה יכול לנסות משהו מבוסס Qt4?

ארתיום, ב־8.9.2008, 19:57

אין לי ב"שלוף" יישומי qt4 בשביל זה אני צריך לקמפל משהו. אולי אתה יכול לעשות copy-paste לטקסט הזה ולראות?

(אגב, qt4 עדיין עובד עם utf-16)

עידו, ב־8.9.2008, 21:54

אין לי כרגע לבדיקה, אבל עד כמה שאני זוכר, excel (גם 2003 וגם 2007) לא מתמודד יפה עם ייצוא של מידע יוניקוד ל csv.

נדב, ב־8.9.2008, 23:03

Excel לא מתמודד טוב עם UTF-8, אחרי המרה ל- UTF-16 (לפחות אצלי) עובד כמו גדול

ארתיום, ב־14.4.2009, 23:45

יישומים שבדקת הם מבוססים Qt3. אתה יכול לנסות משהו מבוסס Qt4?

אגב, בדקתי, זה עובד יפה ב־Qt4

הוסף תגובה:

 
 כתובת דוא"ל לא תוצג
 

ניתן לכתוב תגובות עם שימוש בתחביר Markdown.

חובה לאפשר JavaScript כדי להגיב.

דפים

נושאים