לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תכנות ובניית אתרים
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 08-02-2009, 00:22
  משתמש זכר dorM dorM אינו מחובר  
מנהל
 
חבר מתאריך: 26.07.08
הודעות: 6,473
מהו קידוד וכיצד להגדיר אותו?

קידוד זהו מושג חשוב שכל מפתח מערכת חייב להכיר. בעזרת קידוד אנו מגדירים כיצד כל מידע מסוג מחרוזת (string) ייוצג.
כידוע, מחרוזת היא אוסף של תוים (chars ברבים, char ביחיד), ובדר"כ גודל כל תו הוא 1 בית (byte), כלומר 8 סיביות (bits).
כיוון שגודל תו אחד הוא 8 סיביות, יש אפשרות לייצג 256 (2 בחזקת 8) תוים שונים ע"י שימוש בבית אחד עבור כל תו.
הגדרת הקידוד מוסרת מידע כיצד יש לייצג כל בית שנמצא במחרוזת. לדוגמא, אם הערך המספרי (integer) של בית מסוים הוא 65 בבסיס 10, זה אומר שיש לייצג את הבית בתור האות 'A'.
מכאן ניתן להסיק שיש ליצור טבלאות אמת שייתנו לנו את הייצוג המשמעותי * (מלשון משמעות, הסבר בהמשך) עבור הערך המספרי של כל בית. כל קידוד אחר משתמש בקבוצת תוים שונה, אך לעיתים יכול להיות שקידוד a ישתמש בקבוצת תוים כמו של קידוד b מסיבות היסטוריות שאינן חשובות.
טבלאות אמת כאלו קיימות מספיק, ולפעמים מרוב הכמות העצומה שלהן אפשר להתבלבל בין איזו טבלת אמת (או במילים אחרות, קידוד) כדאי לבחור.


יש 2 סוגי קידוד:
  1. סוג קידוד single byte. בסוג קידוד זה כל בית אחד מייצג תו אחד.
  2. סוג קידוד multi byte. בסוג קידוד זה תו אחד יכול להיות מיוצג ע"י בית אחד, 2 בתים או אפילו שלושה בתים.
    כאן זה קצת יותר מורכב ותלוי בקידוד:
    ישנם קידודי multi byte שבאופן אחיד מייצגים תו אחד ע"י 2 בתים - זה מתקיים בעבור כל התוים הקיימים בקידוד זה.
    ישנו קידוד multi byte שיכול לייצג תו אחד ע"י בית אחד, תו אחר ע"י 2 בתים, ותו אחר נוסף ע"י שלושה בתים. קידוד זה נקרא קידוד UTF-8 ואותו כל מפתח חייב להכיר.

שים לב, ל"קידוד" יש משמעות אחרת מאשר חיתוך תמונה גרפית באופן כזה שתותאם היטב לאפשרויות העיצוב של CSS ולמבנה ה-HTML.
זהו מושג שאנשים רבים נוטים לטעות בו. מומלץ לקרוא כאן וכאן.


מדוע צריך סוג קידוד של single/multi byte?

אני חושב שאי אפשר לשאול "מדוע צריך" אלא למה הקידודים האלה קיימים.
קידודי ה-single byte קיימים עוד מראשית תקופת המחשב, בזמן שבו הטכנולוגיה הייתה לא הכי מתקדמת וכנראה לא הספיקו לחשוב על קידודי multi byte, בין היתר כי לא היה צורך, או שחשבו שאין צורך.
קידודי ה-multi byte קיימים החל מהזמן ששמו לב כי קיים הצורך לייצג מספר רב של תוים תחת אפליקציה אחת. לאחר זמן-מה פותח גם הקידוד UTF-8 שהוא ה"חכם" מבין כל הקידודים, כיוון שהוא משתמש בשיטת קידוד יוצאת דופן (זוהי אותה השיטה של חלוקת כתובת IP ל-class'ים שונים).

באיזה מהם כדאי להשתמש ומתי?

ובכן זה כבר תלוי במפתח המערכת.
מה המפתח מעדיף - חיסכון במקום בכונן הקשיח וכד' אבל ייצוג מספר קטן של תוים, או ביזבוז רב באופן יחסי של מקום אבל ייצוג מספר רב\עצום של תוים?
בימינו אין כזה דבר "ביזבוז מקום בכונן הקשיח". כלומר המקום בכונן הקשיח, בהקשר של תוים, זה עניין זניח שאין לקחת אותו בכובד ראש כאשר מפתחים מערכת. בנוסף נושא ה-
Internationalization (ידוע גם כ- i18n ) תופס תאוצה, ולכן מרבים להשתמש בקידוד UTF-8, שידוע בייצוג מספר עצום של תוים בשיטה שמנסה לחסוך במקום. קרא עוד על W3C i18n Activity.

* למה הכוונה ב- "ייצוג משמעותי של בתים" ?

בפיסקה הראשונה כתבתי שיש טבלאות אמת שנותנות לנו את הייצוג המשמעותי עבור כל בית.
"ייצוג משמעותי" ולאו דוקא "ייצוג גרפי", כמו האות A שמוצגת על המסך, כיוון שישנם מקרים שהמשמעות של הבתים\מידע יכולה להוביל לתהליכים שונים.
העיסוק בשפת תסריט, שזהו למעשה כל ה-Web, מחייב קידוד שמוגדר כראוי כדי שהמנוע שמתעסק עם הבתים\מידע יידע כיצד יש לפעול \ איזה תהליכים יש להריץ.
קוד צד השרת לדוגמא, הוא בתים מסוג מחרוזת שאותו המנוע מפענח ופועל בהתאם לייצוג המשמעותי של התוים. למנוע זה לא משנה כיצד התו נראה, אלא מה הוא אומר.
אותו הדבר בנוגע לקוד צד לקוח. אתן דוגמא: אם ב-JS אני כותב תנאי if, מנוע ה-JS של הדפדפן חייב קודם להבין שמשמעות הבתים שהוא קורא היא "if" (כלומר תנאי) ואז הוא יפעל בהתאם לבתים שכתובים בהמשך ובהתאם לפרוצדורה שהוא מפעיל שמתעסקת עם if.

מה ההבדל בין קידוד לקבוצת תוים?

חשוב להבדיל בין קידוד (encoding) לקבוצת תוים (character set). אנסה לכתוב זאת כפי שאני הבנתי, ולא אדייק כאן כדי לא להבריח אתכם מהאשכול.
קבוצת תוים (או במונח המדויק יותר 'coded character set') זה אוסף של תוים עם ייצוג מספרי (קוד) עבור כל תו.
קידוד (או במונח המדויק יותר 'character encoding form') זה ההמרה והשיטה לייצוג המשמעותי של כל תו מהקבוצת תוים. בפיסקה הראשונה התייחסתי לטבלת אמת בתור קידוד.
כדי לדעת יותר, קראו על Character encoding.

אילו קידודים קיימים?
  • קידוד ASCII - זהו הקידוד הבסיסי ביותר. הוא כולל ספרות (0-9), אותיות באנגלית (גדולות וקטנות), סימני פיסוק ועוד דברים בסיסיים. כל הקידודים האחרים מבוססים על הקידוד הזה. הדבר המיוחד בקידוד זה הוא שכל בית תופס 7 ביטים, ולכן מספר התוים המקסימאלי שניתן לייצג יהיה 128 (מ-0 עד 127).
  • קידודי Windows - אלו קידודים שהוגדרו ע"י החברה Microsoft.
  • קידודי ISO - קידודי single byte. אלו קידודים שהוגדרו ע"י אירגון התקינה ISO. מומלץ לכל מתכנת להתאים את עצמו לתקנים של אירגוני תקינה מקובלים, ולא לתקנים שהוגדרו ע"י חברות פרטיות וקפיטליסטיות.
  • הקידודים ANSI, ISO 8859-1 ו-Windows-1252 - כל הקידודים האלו משתמשים באותה קבוצת התוים. הם מכילים את קידוד ASCII בחלקם התחתון (מ-0 עד 127), וגם מכילים בחלקם העליון קבוצת תוים של אותיות לטיניות המתאימות למספר רב של שפות, ולכן זה קידוד שימושי.
    קידוד Windows-1252 זהו למעשה בדיוק אותו קידוד ANSI. הוא מכונה ANSI בגלל סיבות היסטוריות.
    קידוד ISO 8859-1 זהו הקידוד שהוגדר ע"י אירגון התקינה ISO, והוא שונה בחלקו מקידוד ANSI מבחינת הקידוד, אך כמו שכתבתי קודם - משתמש באותה קבוצה תוים.
  • הקידודים ISO-8859-8, ISO-8859-8-i, Windows-1255 - קידודי single byte. אלו הם קידוד ASCII שהורחב עם אותיות וסימנים של השפה העברית. האותיות הראשונות בשם של הקידוד מעידות על התקן שתחתיו הקידוד הוגדר. יש קידוד ISO של עברית ויזואלית, וקידוד ISO של עברית לוגית. לא ארחיב על זה, אפשר לקרוא כאן ובגוגל.
    שימו לב שגם כאן יש אי-התאמה בקידוד, כך שאתר אינטרנט שקודד ב- Windows-1255 יציג ג'יבריש אם יגדירו לו קידוד ISO של עברית לוגית\ויזואלית.
  • קידוד UTF-8 - קידוד multibyte. משתמש בקבוצת התוים האוניברסלית ששמה Unicode ומקודד אותה בשיטה חסכונית.
    יש קידודים נוספים שמשתמשים בקבוצת התוים Unicode, אך הם מקודדים אותה באופן שונה ופשוט יותר מאשר UTF-8 (לדוגמא, אורך קבוע של 2 בתים מייצגים תו אחד).
    בקידוד זה הוגדר שגודלו של תו אחד יכול להיות עד 4 בתים. מבחינה מעשית אפשרי שגודל תו אחד יהיה עד 6 בתים, אך זה לא יהיה תו תקין\מוגדר.

כמובן שקיימים קידודים רבים נוספים, אך אלו הבסיסיים ביותר שעליכם להכיר בהתחלה.

כיצד יש להגדיר קידוד בצורה נכונה במערכת שאני מפתח?

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

xHTML
יש להוסיף תג meta בין תגי ה-head בצורה הבאה:
קוד:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

כמו כן יש לשלוח בצד השרת כותר שמגדיר את הקידוד, בתנאי שקובץ ה-xHTML מוצג באמצעות קוד צד השרת. דוגמא ב-PHP:
קוד PHP:
 header('Content-Type: text/html; charset=utf-8'); 

בנוסף מומלץ (אך לא חובה) להגדיר קידוד במאפיין accept-charset של התג form:
קוד:
<form accept-charset="utf-8">


XML
קוד:
<?xml version="1.0" encoding="utf-8"?>

כמו כן יש לשלוח בצד השרת כותר שמגדיר את הקידוד, בתנאי שקובץ ה-XML מוצג באמצעות קוד צד השרת. דוגמא ב-PHP:
קוד PHP:
 header('Content-Type: text/xml, charset=utf-8'); 


מסדי נתונים - SQL
יש להגדיר את הקידוד ביצירת הטבלאות (שאילתת CREATE TABLE) וגם מיד לאחר ההתחברות למסד הנתונים.
מלבד הקידוד, ב-SQL יש מושג הנקרא באנגלית collation - משמעותו היא כיצד מסד הנתונים "יתנהג" כאשר יעבוד מול\על מחרוזות (כיצד יתייחס לאותיות גדולות\קטנות בשפה האנגלית וכד'). הגדרה לא נכונה של collation עלולה לגרום לבעיות כאשר תבקשו ממסד הנתונים לבצע פעולה שקשורה למחרוזות. (לדוגמא, שאילתת SELECT עם פיסקת ORDER BY יכולה להחזיר רשומות בסדר לא צפוי). כל מסד נתונים מפרט במדריך למשתמש (בדוקומנטציה) את הגדרות ה-collation בעבור כל קידוד. שים לב(!), לכל קידוד יש collation שונה, חשוב לודא שהגדרת ה-collation היא נכונה ומתאימה לקידוד שהגדרת!
דקל הגדיר בעבר את המושגים character set ו- collation, מומלץ לקרוא.

דוגמא להגדרת קידוד ו-collation בשאילתת יצירת טבלה:
קוד:
CREATE TABLE table_Name ( /* Here you define columns with their appropriate column types etc. */ ) CHARACTER SET utf8 COLLATE utf8_general_ci


דוגמא לשאילתת הגדרת קידוד לאחר ההתחברות למסד הנתונים, תחת מסד הנתונים MySQL (אולי במסדי נתונים אחרים השאילתא שונה):
קוד:
SET NAMES utf8 COLLATE utf8_general_ci

את השאילתא הנ"ל יש להריץ מייד לאחר ההתחברות למסד הנתונים, בכל פעם שמבצעים התחברות. זו לא שאילתא להרצה אחת בלבד! יש להריץ אותה כל פעם מחדש.

קבצים
יש לדאוג שכל קבצי המערכת, המכילים את הקוד של המערכת, יקודדו בקידוד המתאים שבחרת לקודד את כל המערכת. עניין זה קריטי במיוחד כאשר יש בקבצים תוים (כמו אותיות של עיברית) שאינם בתחום קידוד ה-ASCII.


כיצד יש לתקן ג'יבריש בעמוד Web?

הקמתם אתר אינטרנט והוא מציג ג'יבריש?
כנראה לא הגדרתם קידוד כראוי בכל חלקי המערכת.
הדפדפן ניסה להציג את המידע באמצעות הקידוד שהגדרתם (או שלא הגדרתם, ואז הדפדפן משתמש בקידוד ברירת מחדל), והתוצאה היא ג'יבריש.
ניתן להסיק שיש אי-התאמה בין המידע המקודד בקידוד X לבין ההגדרה של הקידוד (קידוד Y) שנשלחה לדפדפן ושניסה לייצג את המידע באמצעות קידוד Y.

קודם יש לבדוק מהו הקידוד שהגדרתם בתג meta שנמצא בין תגי ה-head.
לאחר מכן יש לודא שזהו אותו הקידוד שמסרתם לדפדפן בכותר Content-Type (שליחת כותרים נעשית דרך צד שרת).
אח"כ יש לבדוק שזהו אותו הקידוד שהגדרתם לטבלאות במסד הנתונים (בשאילתת CREATE TABLE) ול-connection למסד הנתונים (בשאילתת SET NAMES).

אם מצאתם קידוד שונה באחד מהאפליקציות הנ"ל, יש לתקן את ההגדרה של הקידוד לקידוד הרצוי, כדי שהקידוד יהיה אחיד בכל המערכת.

אשכולות בפרש על תיקון קידוד:

מדוע הגדרה נכונה ואחידה של קידוד זה עניין כל כך קריטי?

מלבד העובדה שאי הגדרה של קידוד עלולה לגרום לבעיות בתצוגה אצל צד לקוח (המשתמש שצופה באתר),
ישנם מקרים שבהם הגדרה לא נכונה או אי-הגדרה של קידוד עלולה לגרום לפריצות בקוד שכתבתם, וביניהם SQL Injections.
תארו לכם מצב בו הגדרתם קידוד multi byte אצל מסד הנתונים וגם עבור ה-input המגיע לקוד צד השרת, אך צד השרת "חושב" שזהו קוד ASCII או קוד single byte אחר.
כאשר תנסו לעשות "הברחה" לתוים כמו לוכסן אחורי (backslash) בצד שרת על מנת למנוע הזרקות SQL, יכול להיווצר מצב בו למעשה קוד צד השרת ייטעה ויחשוב שתו מסוים שגודלו 2 בתים מכיל בתוכו תו שהוא צריך להבריח, כמו גרש ( ' ).
במידה והוא יבריח אותו, הבית שמשמעותו "גרש" עשוי "לצאת" מהתחום של התו שגודלו 2 בתים, ואז המצב החדש שיהיה זה שהגרש לא הוברח, מהפרספקטיבה של מנוע מסד הנתונים שמוגדר אצלו קידוד multi byte.
אני יודע שקצת קשה להבין את זה מההסבר שלי, לכן לקריאה נוספת:_________________________

הפניות נוספות:

נערך לאחרונה ע"י dorM בתאריך 08-02-2009 בשעה 00:25.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #6  
ישן 09-02-2009, 14:41
צלמית המשתמש של tnadav1
  משתמש זכר tnadav1 tnadav1 אינו מחובר  
 
חבר מתאריך: 02.10.05
הודעות: 2,355
שלח הודעה דרך MSN אל tnadav1
בתגובה להודעה מספר 5 שנכתבה על ידי iBot שמתחילה ב "אני לא מסכים איתך, עבודה..."

ואני לא מסכים איתך. UTF-8 זה סוג של ברירת מחדל בכל העולם (מסיבה טובה). נגיד שזה עובד טוב אצלך, אבל השרת שהעלת עושה בעיות עם הקידוד שבחרת... אתה בבעיה.

בקשה מאוד נפוצה (גם בדרך כלל מבקשים דברים כאלה שאתה באמצע העבודה, והתחלת לבנות כבר את כל הבסיס של המערכת. ממני ביקשו שהייתי ממש בסוף) היא להוסיף שפה לאתר. אם לא השתמשת בקידוד שהוא multibyte, אתה בבעיה.

תראה את כל הבעיות עם הג'יבריש בפורום, ברובם המוחלט המשתמש משתמש בקידוד שהוא לא UTF-8.
אני הכנסתי מההתחלה את ההרגל של להשתמש ב- UTF-8, ומזל, כי אף פעם לא הייתה לי בעייה של ג'יבריש.

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

ולשאלה שלך, מן הסתם UTF-8, זה הרגל טוב וייחסוך לך הרבה זמן בהמשך.

UTF-8 זה מה שכולם צריכים להשתמש בו כי המקום הנוסף שהקידוד ייקח הוא זניח. הזמן שהוא יחסוך בעל ערך הרבה יותר גדול מהמקום ש-"ייאבד".
_____________________________________



נערך לאחרונה ע"י tnadav1 בתאריך 09-02-2009 בשעה 14:44.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 10:45

הדף נוצר ב 0.06 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר