Featured image of post فرق utf-8 با unicode چیه؟

فرق utf-8 با unicode چیه؟

این پست که درباره فرق unicode و utf-8 بود خیلی مفید بنظرم رسید، برای همین خلاصه‌ای ازش رو اینجا می‌نویسم.

زمانی که ASCII معرفی شد کلا برای حروف انگلیسی ساخته شده بود، و البته یکسری از کاراکتر‌ها و دستورات دیگه. مثلا برای اسپیس کد 32 و مثلا برای حرف A از کد 65 داخلش استفاده میشد. ولی کد‌های قبل 32 چی؟ اون‌ها برای دستورات استفاده میشد مثلا کد 7 برای صدای beep هست!

تمامی این کاراکتر‌ها کلا توی 7 بیت قرار می‌گیرن و فضای بیشتری نیاز ندارن. مثلا اگه حرف z رو درنظر بگیریم، کد اسکی‌ش میشه 122 و باینری 122 میشه 1111010 و همینطور که می‌بینید، با فقط هفت بیت حروف انگلیسی، اعداد، سیمبل‌ها و دستورات رو می‌تونیم داشته باشیم، اما کامپیوتر ها با 8 بیت کار می‌کنند، پس پیاده سازی ascii داخل کامپیوتر یک بیت اضافه‌ای به ما میده!(آخرین بیت سمت چپ). برای همین از کد 128 تا 255 برای هیچکاری داخل تیبل ascii استفاده نمیشه.

اینجاست که شرکت‌ها و برنامه نویس ها تصمیم می‌گیرن اون بیت آخر رو برای کار های خودشون استفاده کنند. همچنین هر زبانی مثلا یونانی برای خودش یه کد پیج داشته. مثلا توی بعضی از سیستم عامل ها از کد 130 برای کاراکتر é استفاده میشده، و یه ورژن دیگه‌ای از همون سیستم عامل (DOS) از این کد برای کاراکتر ג استفاده میشده.

اینم باید بگم که همه قبول کرده بودن که تمامی کد های زیر 128 دست نخورده بمونه خوشبختانه. اینکه کدهای بالای 128 نماینده چه کاراکتری باشه بستگی داره به اینکه از چه code page استفاده می‌کردن. مثلا code page 862 در اسرائیل استفاده میشده و 737 در یونان. حالا سیستم عامل DOS از کلی کد پیج ساپورت می‌کرده، ولی همزمان نمیشده توی یک فایل تکست از دو زبان استفاده کنی.

حالا عجیب‌تر اینکه این سسیتم توی زبان هایی مثل چینی بدرد نمی‌خوره، چون خب از ‘حرف’ استفاده نمی‌کنند و کاراکترهاشون نماده و هزاران کاراکتر دارند، پس توی 8 بیت جا نمی‌شن. خب اینا چیکار کردن؟ از چیزی به اسم DBCS استفاده کردن این یعنی double bytes character set درواقع برای پیاده‌سازی زبان چینی باید تعداد بایت ها رو دو برابر می‌کردن، این خودش مشکل داره! اینکه تایپ یک کاراکتر ساده‌ست(حرکت رو به جلو) اما اگه بخای به عقب برگردی، این یه چالشه، چون نمی‌دونی کاراکتری که تایپ کردی یک بایتی بوده یا دو بایتی(این مشکل برنامه نویس‌ها بوده)

تا اینجا انچنان مشکلی هم نداشتیم، اما وقتی پای اینترنت به کامپیوتر‌ها باز شد، دیگه اینجا بود متن‌ها توی سیستم‌های مختلف به خوبی کار نمی‌کردند، پس و unicode اختراع شد.

به صورت خلاصه unicode به ازای هر کاراکتری یک کد داره (تا اینجا مثل ascii)، که بهش میگن code point،

unicode طوری ساخته شده که حتی اگه در آینده‌هم کاراکتری و یا زبانی اختراع بشه، با unicode میشه یک کد منحصر بفرد بهش اختصاص داد. مثلا برای کاراکتر A از کد U0041 استفاده میشه، و یا برای مثال U+0048 U+0065 U+006C U+006C U+006F. میشه Hello. این کد‌ها هگزادسیمال هستند.

اوکی حالا سوال اینجاست که ما برای هرکاراکتری یک کد در نظر گرفتیم، اوکی خب چطوری روی هارد قراره ذخیره‌ش کنیم؟

در حالت اول و خب خیلی ساده میشه اکثر کد ها رو داخل 16 بیت دخیره کرد، اما دو مشکل وجود داره:

  1. فضای بیشتری برای ذخیره می‌گیره
  2. اینکه خب اینهمه تکست که از قبل نوشته شده، یکی باید همه اونها رو تبدیل کنه. باید بتونیم یک راه backward compatible بنویسیم.

اینجاست که جادوی utf-8 که یک encondig هست میاد وسط، توی utf-8 از 0 تا 127 توی همون 8 بیت ذخیره می‌شه و چیزی که به فضای بیشتری نیاز داره چی؟ وقتی کاراکتری بیشتر از 127 (یعنی نیاز به بیش از 7 بیت) نیاز داشته باشه، UTF-8 از چند بایت استفاده می‌کنه: بایت اول یه “الگو” داره که نشون می‌ده این کاراکتر چند بایتیه، و بایت‌های بعدی با 10xxxxxx شروع می‌شن. اینطوری کامپیوتر می‌فهمه این یه کاراکتر چندبایتیه و چطوری باید رمزگشایی‌ش کنه.

comments powered by Disqus
قدرت گرفته از Hugo
قالب Stack ساخته شده توسط Jimmy