• الإعلانات

    • فيصل الحربي

      تسجيل عضوية جديدة في المنتدى   01/31/2016

      السلام عليكم ورحمة الله وبركاته  عزيزي العضو الجديد :  حاليا رسالة الإيميل لتأكيد صحة إيميلكم تذهب للبريد العشوائي ( جاري حل المشكلة )  فإذا لم تجد رسالة التحقق من إيميلكم في صندوق الوارد لديكم إتجه للبريد العشوائي ( JUNK)  وقم بتفعيل إشتراككم من هناك   

البحث في المنتدى

Showing results for tags 'unicode'.

  • البحث بالتاقات

    اكتب الكلمات المفتاحيه بينها علامه الفاصله
  • البحث بكاتب الموضوع

تم إيجاد 3 نتيجة

  1. ترميز الحروف

    بسم الله الرحمن الرحيم العقل الذى وهبه الله للإنسان يستطيع التفرقة بين الكلمات المكتوبة بلغته و أى لغه أخرى و هذا على خلاف الأله التى تحتاج لوسيله محدده للتفرقة بين حروف اللغات التى يتم الكتابة بها. هذه الوسيلة تسمى بترميز الحروف و هى محور هذا الموضوع[1]. فى هذا الموضوع مقدمةترميز ASCIIصفحة المحارف Codepageصفحة المحارف ذات الحجم المتغير Multi-byte Codepageترميز Unicodeترميز UTF-8ترميز UTF-16ترميز UTF-32علامة BOMمكتبة charsetخاتمةمقدمة اللغات الطبيعية القائمة على حروف، كل حرف بها له 3 خصائص: صوت: و هو الطريقة التى يتم نطق الحرف بها.ترتيب: و هو موقع الحرف داخل السلسة الهجائية الخاصه باللغه.شكل: و هو الهيئة التى يتم رسم هذا الحرف بها اثناء الكتابة.فى علوم الحاسب العلم الذى يختص بدراسة أصوات الكلام هو Speech Processing و العلم الذى يختص بدراسة شكل الحرف و رسمه هو Typography. أما ترتيب الحرف فالمفهوم داخل الحاسب يختلف على ما هو عليه فى اللغات الطبيعية و المجال الذى يختص بدراسته هو Character encoding. يعتبر مجال Character encoding من أهم مجالات الحاسب التى لا يهتم بها الكثيرون، فبسببه أمكن رسم الحروف و طباعتهم و التعامل معهم، و قد مر هذا المجال بالعديد من المراحل إلى أن وصل لمرحلة الإستقرار التى نشهدها حاليا. فى الماضى دعت الحاجه لوجود وسائل لإرسال و إستقبال الرسائل النصية و أول هذه الوسائل هى شفرة مورس و التى قامت بإعطاء كل حرف سلسلة من الحالات المنطقيه التى تتكون من قيمتين فإما (صفر و واحد) أو (نقطه و شرطه) أو (مضاء و مطفي) و هكذا. شفرة مورس تمثل ببت واحد - One Bit - و ذلك لطبيعة اى عنصر فى السلسلة. أحد المشاكل فى شفرة مورس هى انها ديناميكية حيث ان كل حرف لا يستغل مساحه ثابته و لكن متغيره و تحدد بالحرف نفسه و ايضا لابد من وجود شخصين مدربين عليها ليستطيعوا إرسال و استقبال الرسائل بها. مر بعض الوقت و تم إبتكار شفرة بودت التى أستخدمت مساحه ثابته للحرف - تسمى كود الحرف - و كانت 5 بت و استطاعت تمثيل 32 حرف منهم حروف اللغه الإنجليزية الكبيرة فقط. بعدها بفترة قام دونالد ميوراى بإجراء بعض التعديلات على شفرة بودت و أضاف إليها بعض الحروف الغير مرئية و سميت شفرة ميوراى و قام بإستخدام الشفرة المعدلة داخل اله كاتبه بسيطه ذات ازرار تكتب بها و عندما تضغط على زر نهاية السطر يتم إرسال محتويات السطر دفعة واحده[2]. شفرة ميوراى كانت خطوة كبيرة فى عالم إرسال البيانات حيث من بعد نشره لها بفترة ليست كبيرة تم إضافة العديد من الحروف الغير المرئية مثل المسافه الخالية للفصل بين الكلمات و حرف أخر لإحداث جرس عند إتمام إرسال السطر، هذه الشفرة المعدلة إستخدمت 6 بت فقط و أستطاعت تمثيل 64 حرف و ظل إستخدام هذه الشفرة المعدلة لفترة طويلة. عندما تم توسيع المساحه المستخدمه للحرف إلى 6 بت تم إبتكار العديد من وسائل لترميز الرسائل و أكثرها إنتشارا وقتها كان من تصميم IBM و إسمه Binary-Coded Decimal حيث تم تقسيم الـ 6 بت إلى جزئين و كل منهم يمثل الأرقام من صفر و حتى 7 و بعدها تم إستخدام هذه الأرقام فى مجموعات ذات معنى متشابه. بعد فترة من الزمن تم إقتراح إضافة الكود shift للحروف الموجوده و ذلك ليعطى معنى أخر لكل كود موجود و بالتالي يتم مضاعفة الحروف المستخدمه فبدلا من 64 حرف يصبحوا 128 و أصحاب الفكرة أقروا بأن هذه الوسيلة ستسمح بتمثيل الحروف الكبيرة و الصغيرة بالإضافة لأكواد التنسيق و الأرقام و أضافوا أن القيم المرسلة ستكون صغيرة، و لكن بعد التصويت تم رفض هذا الإقتراح و السبب الذى أجمتعوا عليه أنه إذا حدث خطأ فى إرسال البيانات فوجود الكود shift سيجعل الرسالة بأكملها تالفه و لا يمكن إسترجاع أى شئ منها[3]. رفض إضافة الكود shift أدى إلى إضافة بت جديد للمساحه الموجوده لتصبح 7 بت و هذا أدى إلى ميلاد ASCII.     ترميز ASCII وجدت العديد من المحاولات لتصميم ترميز بمساحة 7 بت و أنجح هذه المحاولات كان فى عام 1963 حيث قامت منظمة American Standards Association بتصميم ترميز يحتوى على 128 رمز بمساحة 7 بت للرمز الواحد و سمي بـ American Standard Code for Information Interchange و إختصارا ASCII. السبب فى إستخدام الكلمه رمز و ليس الكلمة حرف عائد إلى أن تصميم ASCII الأصلي كان يحتوى على أكواد لرموز غير مرئية و حروف و علامات ترقيم و أرقام و غيرهم و لهذا فالكلمه رمز تعطي معنى أدق و أعم من غيرها. التصميم الأصلي قام بحجز أول 32 كود للعمليات الغير مرئية و البقية لتمثيل الحروف و الأرقام و علامات الترقيم و غيرهم، و لكن فى ذلك التصميم لم يتم تحديد طبيعة معظم الأكواد الـ 32 الأولى و هذا سبب تضارب بين الأجهزة التى صممتها بعض الشركات حيث بعضهم كان يستخدم هذه الأكواد لتعنى شئ فى حين أخرين يستخدموا نفس الأكواد لتعنى شئ أخر[4]. بالإضافة لهذه المشكلة ظهرت مشكلة إرسال بعض الأكواد الغير مرئية ليتم تنفيذها على الجهاز الهدف بدل من تنفيذها على جهاز المصدر، هذه المشكلة تم حلها بإستخدام الكود ESC و الذى يتم إرساله و بعده سلسلة من الحروف بهيئة معينه و التى عندما يتم إستقبالها على الجهاز الهدف يتم تحويلها لكود و يتم تنفيذه. الكود ESC أظهر سلسلة جديدة من الأكواد عرفت بالإسم ANSI Escape code. تصميم ASCII كان يحتوى على الحروف الإنجليزية فقط و هذا أدى العديد من الدول بتغيير قيم بعض الحروف لأخرين ليستطيعوا تمثيل لغاتهم، و هذا جعل التضارب يزيد و جعل ASA فى عام 1967 تقوم بتثبيت بعض رموز ASCII و ترك البعض ليتم إستبدالهم من خلال اللغات الأخرى. التوثيق الذى تم إصداره فى 1967 تم ترك بعض الحروف من ASCII للإستخدام الدولي و الذى أدى لظهور بعض المشاكل منها عدم قيام بعض الدول بتحديد حروف للاماكن المتاحه. من الأكواد التى تركت للإستخدام الدولي رمز القوس المفتوح و المغلق و الذى جعل مصممي لغة الـ C و بعض اللغات الأخرى بإضافة ما يسمى Trigraph Sequence داخل تصميم لغاتهم و ذلك ليتم إستخدامهم بدلا من بعض الرموز الغير مدعومه فى ترميز لغة معينه. فى عام 1968 تم إستخدام الإسم US-ASCII للإشارة للنسخه التى تحتوى على الحروف الإنجليزية و الرموز التى تم وضعها من قبل ASA و تم تشيجع إستخدام هذا الإسم حيث كان يوجد وقتها بعض النسخ الأخرى من ASCII مثل German-ASCII و French-ASCII و غيرهم. فى عام 1986 تم الإستقرار على محتوى US-ASCII و الذى يتم إستخدامه حتى يومنا هذا، و هو كالتالي: ╔═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╦═════╗║ NUL ║ SOH ║ STX ║ ETX ║ EOT ║ ENQ ║ ACK ║ BEL ║ BS ║ HT ║ LF ║ VT ║ FF ║ CR ║ SO ║ SI ║║ 001 ║ 001 ║ 002 ║ 003 ║ 004 ║ 005 ║ 006 ║ 007 ║ 008 ║ 009 ║ 00A ║ 00B ║ 00C ║ 00D ║ 00E ║ 00F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ DLE ║ DC1 ║ DC2 ║ DC3 ║ DC4 ║ NAK ║ SYN ║ ETB ║ CAN ║ EM ║ SUB ║ ESC ║ FS ║ GC ║ RS ║ US ║║ 010 ║ 011 ║ 012 ║ 013 ║ 014 ║ 015 ║ 016 ║ 017 ║ 018 ║ 019 ║ 01A ║ 01B ║ 01C ║ 01D ║ 01E ║ 01F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ SPC ║ ! ║ " ║ # ║ $ ║ % ║ & ║ ' ║ ( ║ ) ║ * ║ + ║ , ║ - ║ . ║ / ║║ 020 ║ 021 ║ 022 ║ 023 ║ 024 ║ 025 ║ 026 ║ 027 ║ 028 ║ 029 ║ 02A ║ 02B ║ 02C ║ 02D ║ 02E ║ 02F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ 0 ║ 1 ║ 2 ║ 3 ║ 4 ║ 5 ║ 6 ║ 7 ║ 8 ║ 9 ║ : ║ ; ║ < ║ = ║ > ║ ? ║║ 030 ║ 031 ║ 032 ║ 033 ║ 034 ║ 035 ║ 036 ║ 037 ║ 038 ║ 039 ║ 03A ║ 03B ║ 03C ║ 03D ║ 03E ║ 03F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ @ ║ A ║ B ║ C ║ D ║ E ║ F ║ G ║ H ║ I ║ J ║ K ║ L ║ M ║ N ║ O ║║ 040 ║ 041 ║ 042 ║ 043 ║ 044 ║ 045 ║ 046 ║ 047 ║ 048 ║ 049 ║ 04A ║ 04B ║ 04C ║ 04D ║ 04E ║ 04F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ P ║ Q ║ R ║ S ║ T ║ U ║ V ║ W ║ X ║ Y ║ Z ║ [ ║ \ ║ ] ║ ^ ║ _ ║║ 050 ║ 051 ║ 052 ║ 053 ║ 054 ║ 055 ║ 056 ║ 057 ║ 058 ║ 059 ║ 05A ║ 05B ║ 05C ║ 05D ║ 05E ║ 05F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ ` ║ a ║ b ║ c ║ d ║ e ║ f ║ g ║ h ║ i ║ j ║ k ║ l ║ m ║ n ║ o ║║ 060 ║ 061 ║ 062 ║ 063 ║ 064 ║ 065 ║ 066 ║ 067 ║ 068 ║ 069 ║ 06A ║ 06B ║ 06C ║ 06D ║ 06E ║ 06F ║╠═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╬═════╣║ p ║ q ║ r ║ s ║ t ║ u ║ v ║ w ║ x ║ y ║ z ║ { ║ | ║ } ║ ~ ║ DEL ║║ 070 ║ 071 ║ 072 ║ 073 ║ 074 ║ 075 ║ 076 ║ 077 ║ 078 ║ 079 ║ 07A ║ 07B ║ 07C ║ 07D ║ 07E ║ 07F ║╚═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╩═════╝و الـ Control Characters هم: 00 = NUL = Null character01 = SOH = Start of Header02 = STX = Start of Text03 = ETX = End of Text04 = EOT = End of Transmission05 = ENQ = Enquiry06 = ACK = Acknowledgment07 = BEL = Bell08 = BS = Backspace09 = HT = Horizontal Tab0A = LF = Line feed0B = VT = Vertical Tab0C = FF = Form feed0D = CR = Carriage return0E = SO = Shift Out0F = SI = Shift In10 = DLE = Data Link Escape11 = DC1 = Device Control 112 = DC2 = Device Control 213 = DC3 = Device Control 314 = DC4 = Device Control 415 = NAK = Negative Acknowledgment16 = SYN = Synchronous idle17 = ETB = End of Transmission Block18 = CAN = Cancel19 = EM = End of Medium1A = SUB = Substitute1B = ESC = Escape1C = FS = File Separator1D = GS = Group Separator1E = RS = Record Separator1F = US = Unit Separator7f = DEL = Delete      صفحة المحارف Codepage كانت أحد المشاكل فى ASCII انه لا يوجد توثيق للنسخ المعدله حيث كل دوله كان لها نسختها الخاصه من ASCII التى تطورها و ترعاها، هذا التشتت جعل ISO تصدر اول توثيق لها فى مجال تبادل المعلومات و أسمته ISO 646 توثيق ISO 646 كان يماثل توثيق ASCII مع ترك بعض الأماكن المحدده للإستخدام الدولي، و كل من استخدم هذا التوثيق و تقيد بقيوده تم تثبيت نسخه تماثل التى قام بتحديدها. مع العلم أن IBM كانت من المشتركين فى تصميم ASCII إلا أن تصميم أجهزتها كان يستخدم 6bit BCD و الذى كان من الصعب إستبداله بـ ASCII لذا قامت IBM بمد المساحه من 6bit إلى 8 بت و أقترحت توسيع ASCII لتصبح 8 بت و لكن تم رفض هذا الإقتراح. قامت IBM بتطوير نظام BCD إلى 8 بت و هذا ادى إلى توسيع كل خانة لتشمل الأرقام من 0 إلى 9 و قامت بتطوير أجهزتها للعمل به. هذا التصرف من IBM أدى لتطوير العديد من المنشئات لخطوط أنتاجهم لجعلها 8 بت بدلا من 7 بت و تم جعل البت الثامن بصفر[5] و ذلك لإتمام التوافق مع ASCII. مع وجود معالجات تقوم بنقل 8 بت دفعه واحدة قامت العديد من المنشئات بإستغلال البت الثامن لأغراضهم الخاصه فى منتجاتهم لتوسيع المساحه المستخدمه لترميز الحروف، مع إنتشار هذا الإسلوب ظهر المسمى Extended ASCII و الذى يعنى إستخدام البت الثامن لترميز عناصر أخرى مع وجود ASCII داخل المدى 0 إلى 127. المسمى Extended ASCII أدى البعض للإعتقاد أن ASCII تم تطويرها لتصبح 8 بت لتشمل بعض الرموز الجديده و هذا غير صحيح. فى الماضي تم إستخدام المصطلح Page للإشارة إلى مساحه ثابته من الذاكرة، و حيث أن الـ 8 بت تنقسم لجزئين متساويين كل منهم يستطيع تمثيل 128 قيمة فتم ترك الجزء العلوى فى المدى 0 إلى 127 لـ ASCII و تم تسمية الجزء الأخير بالإسم Code page. كانت IBM هى من أبتكر المصطلح[6] Code page و أول إستخدام له كان مع تطوير ترميز BCD إلى EBCDIC و بعدها تم إستخدامه داخل نظام التشغيل PC DOS و من وقتها و أصبح المصطلح شائع من شركات كبرى مثل مايكروسوفت و غيرها. مع أن EBCDIC لم يكن ذات شهره عالية إلا أن الـ Code pages التى تم إستخدامها داخل نظام PC DOS أصبح لها شهره عالية لأنها قامت بتمثيل العديد من اللغات و أولهم و أشهرهم هى Code page 437، هذه الـ code pages كان لها العديد من الأسماء مثل CP-n و OEM-n و PC-n حيث n هو مجرد رقم و مع العلم ان الثلاث مسميات قد يشيروا إلى صفحة محارف واحدة إلا أن الرقم قد يكون مختلف و هذا عائد إلى انه توجد العديد من نسخ DOS و كل منهم موجه لبيئة محدده و من هنا جاء إختلاف المسميات. قامت منظمة ISO بإعادة النظر فى توثيقها القديم ISO 646 و قامت بإصدار توثيق جديد بالإسم ISO 8859 ليواكب التطورات و قامت فيه بإستخدام البت الثامن لبعض من اللغات الأخرى و أعطتها الإسم ISO 8859-n حيث n هو رقم من 1 إلى 16 ماعدا 12 فلم يتم كتابة صفحة محارف له. عندما قامت ميكروسوفت بتصميم نظام تشغيل ويندوز قامت بكتابة صفحات محارف خاصه بنظامها و تأخذ الإسم Windows-125n حيث n هو رقم الصفحة فى المدى من 0 إلى 8. أيضا داخل نظام ويندوز ستجد صفحات المحارف التى صممت لـ DOS و لكنها بالإسم OEM-n بدلا من الإسم CP-n. و لكن حتى مع كل هذه التطورات وجدت لغات تحتوى على رموز بالألاف و التى كان من المستحيل ترميزها داخل 8 بت و هذا أدى إلى ظهور مصطلح جديد يسمى Multi-byte Codepage.     صفحة المحارف ذات الحجم المتغير Multi-byte Codepage الحل المقترح كان بجعل ترميز الحروف على قسمين كالتالي: ترميز بحجم ثابت: و أى رمز به يتم تمثيله بمساحه ثابته. هذا الترميز يسمى بـ Fixed-width Character Encoding، مثال على هذا الترميز ASCII.ترميز بحجم متغير: و أى رمز به يتم تمثيله فى مساحه ثابته و يمكن تكرار هذه المساحه عدد معين من المرات. هذا الترميز يسمى بـ Variable-width Character Encoding.لحل مشكلة اللغات التى تحتوى على أكثر من 128 رمز تم إستخدام إسلوب الترميز بحجم متغير و تطبيقه على المدى FF-80 حيث تم تقسيم هذا المدى إلى ثلاثة أقسام: singleton: وهى أكواد قيمتها تمثل رمز محدد، مثل أن الكود 5916 يمثل الحرف Y داخل ASCII.lead-units: و هو كود أو أكثر يمثل بداية سلسلة من عدة أكواد و هم مجتمعين يمثلوا الرمز. (سيتم تفصيل هذه النقطه لاحقا).trail-units: و هو كود أو أكثر يمثل نهاية السلسلة التى بدءت بالـ lead-units.مع العلم أن الـ lead-units قد تكون كود واحد أو أكثر إلا أن أغلب صفحات المحارف ذات الحجم المتغير إن لم يكن جميعهم يستخدم كود واحد فقط لتيسير عملية التكويد. لنأخذ مثال لتقريب الفكرة، لنفترض ان لدينا الحروف (أ ت ج ح م ي لأ) و نريد إستخدام صفحة محارف ذات حجم متغير، حيث الأكواد بها لابد أن تكون عبارة عن سلسلة من lead-units و trail-units لذا قيمة هذه الحروف ستكون كالتالي: أ : EE 80 01 FFت : EE 80 0E EFج : EE 80 11 99ح : EE 80 11 9Fم : EE 80 1F 6Aي : EE 80 2A 3Bلأ : EE 83 05 0Aصفحات المحارف ذات الحجم المتغير تقوم بتحديد كود البداية (ذات اللون الأزرق) و الذى عند تحديده يتم تحميل صفحة محارف داخلية ليتم من خلالها تحديد الرمز المطلوب بناءا على أكواد النهاية (ذات اللون الأخضر) و مع كل كود يتم قرائته يتم معرفة أحتمالات القيم القادمة و أيهم قد يكون هو كود نهاية السلسلة. أكواد الحروف التى تراها بالأعلى هى من محض خيالي حيث فى الأغلب ستجد أن أكبر حرف فى صفحة محارف ذات حجم متغير يأخذ ثلاثة أكواد فقط و لكني أحببت كتابتهم بهذا الإسلوب لإعطائك فكرة تصميمهم، أيضا تصميم أكواد الرموز يكون فى الأغلب عشوائي و حسب الأكواد التى لم يتم إستخدامها. مع أن هذا الإسلوب نجح فى تمثيل كافة رموز اللغات إلا أن له عيوب كثيره منها: الأكواد لا تمثل قيمة رقمية صحيحه يمكن الوصول بها للرمز المطلوب، فمثلا داخل ASCII الكود 5916 هو رقم صحيح يمثل الحرف Y، أما الأكواد المستخدمه فى هذا الترميز فلا معنى لها.الوسيلة الوحيده للبحث داخل نص يحتوى على هذه الأكواد هو بقرائتهم بالكامل لإنك لا تعرف طول السلسلة و هذا يسبب بطء كبير فى عمليات معالجة النصوص.وجود خطأ فى أحد الأكواد يتلف النص بأكمله لأنه كما ترى الـ trail-units قد تحتوى على أكواد إذا تم قرائتهم وحدهم فإنهم يمثلوا حروف موجوده أو أكواد بداية لسلسلة أخرى.هذا بالإضافة لبعض العيوب الأخرى. و لكن حتى مع النجاح الذى حققته هذه الطريقه إلا أنه لازالت مشكلة إستخدام أكثر من لغه داخل نص واحد موجوده و لا حل لها. كل هذه المشاكل و غيرهم تم إيجاد لهم حلول مرنة و يسيرة من خلال منظمة Unicode.     ترميز Unicode فى عام 1988 قام جو بيكر بطياعة توثيق مبدئي و أطلق عليه الإسم Unicode و الذى محتواه كان يهدف إلى إيجاد ترميز موحد لكل الرموز بكل لغات العالم و ذلك بمد المساحه المستخدمه لـ ASCII من 8 بت إلى 16 بت و أطلق إسم مجازى على المساحه الموسعه و هو "wide ASCII" و أوضح أن إسم التوثيق يعني "Unique, Unified, Universal encoding". فى عام 1990 تم إنشاء مجموعة بالإسم Unicode group و قام أعضائها بالإضافه لأعضاء من ISO بالعمل على إعطاء كافة حروف لغات العالم وصف و كود محدد داخل Unicode. فى عام 1991 تم إنشاء منظمة غير ربحية بالإسم Unicode Consortium و إختصارا Unicode، و تم إصدار أول توثيق لها فى نفس العام و تم تحديد به أن المساحه التى يستهلكها الحرف الواحد هى 16 بت. و فى الإصدار الثانى تم إضافة كافة حروف Han ليكتمل توثيق كافة الحروف المستخدمه عالميا. العمل على تطوير الإصدار الثاني تم بالتعاون بين Unicode و ISO، و بعد إصدار ذلك التوثيق من Unicode قامت ISO بإصدار توثيق خاص بها بالإسم Universal Character Set و له الكود ISO/IEC 10646 و كلاهما يتماثل فى المضمون مع إختلاف بعض المصطلاحات، أيضا كلاهما له نفس قاعدة بيانات الحروف زاد الأول أو نقص عن الأخير ببعضهم. قاعدة بيانات الحروف لها الإسم UCD و هذا الإسم مع توثيق Unicode يعنى Unicode Character Database و مع ISO فإنه يعني Universal Character set Database و مع أن مصطلح الإختصار مختلف إلا أن كلاهما يشير إلى نفس البيانات. داخل قاعدة بيانات الحروف كل حرف له رقم فريد لا يتكرر فى المدى من 016 إلى 10FFFF16، هذا الرقم يسمى Unicode scalar value أو character value طبقا لـ ISO أى القيمة الصحيحه للحرف، و كل حرف يتم إعطائه وصف محدد غير مرتبط بشكل حيث أن الحرف الواحد داخل لغه معينه قد يكون له أكثر من شكل و لكن له وصف واحد فريد مرتبط به. تبعا لذلك التعريف فإنك ستجد بداخل قاعدة البيانات حرفين قد يكون لهم نفس الشكل و لكن لأن كل منهم فى لغه مختلفه فإن وصف الحرف مختلف و بالتالي كل منهم هو حرف مختلف.   فى التوثيق الأول من Unicode تم إستخدام ترميز بمساحة 2 بايت و تم إعطائه الإسم UCS-2 و أستطاع تمثيل كافة القيم الصحيحه للحروف فى المدى من 016 و حتى FFFF16 و تم نبذ هذا الترميز عندما تم توسيع قاعدة البيانات من FFFF16 إلى 10FFFF16. القيمة الصحيحه للحرف تستخدم للوصول إليه داخل قاعدة البيانات و حيث أن أكبر قيمة يتم حفظها داخل 4 بايت فإن التعامل المباشر مع هذه القيمه فى الحفظ و الإسترجاع و المعالجه داخل الذاكرة غير عملى و لهذا تم إيجاد طريق لترميز تلك القيمه و التى من شأنها جعل عملية الحفظ و الإسترجاع تتم لمساحه أصغر و ايضا عملية إستخلاص قيمة الحرف من الترميز يسيرة و سريعة، الترميز الإفتراضي المستخدم فى عملية الترميز فى كلا التوثيقان هو UTF-16 أو Unicode Transformation Format 16-bit.   داخل توثيق ISO تم تحديد ترميزان و هم UCS-2 و UCS-4، أما الأول فقد ذكرت أنه تم نبذه و الأخير يستخدم لحفظ القيمة الصحيحه للحرف داخل 4 بايت. داخل توثيق Unicode تم تحديد الترميز UTF-16 كبديل لـ UCS-2 و أيضا ترميز UTF-32 كتضمين لـ UCS-4، بالإضافة لهؤلاء تم إضافة ترميز أخر و هو UTF-8 و الذى تم إبتكاره كبديل لـ ASCII. فى الوقت الحالي توثيق ISO يستخدم UTF-8 -16 -32 لترميز القيمة الصحيحه للحرف و داخل التوثيق تم إستخدام المصطلح code-point ليعنى القيمة الصحيحه للحرف فى المدى المسموح به داخل الترميز. كل ما ذكرناه ينطبق على التعامل مع قاعدة بيانات الحروف و ترميز القيمة الصحيحه لكل حرف بها و إلى هنا هذا هو أقصى ما يصل إليه توثيق ISO، أما توثيق Unicode فيستمر إلى أبعد من ذلك حيث يحتوى على وسائل للبحث داخل النصوص التى تحتوى على أكثر من لغه بالإضافة لقواعد كتابة أكثر من لغة معا و غيرها[7]. داخل Unicode الترميز UTF-X - حيث X هو عدد البتات - يتم الإشارة إليه بعدد البتات التى يتم إستخدامها داخل الترميز كوحدة بيانات واحدة و تسمى code-unit، أيضا يمكن ان يتم حفظ قيمة الـ code-point داخل وحدة واحدة أو أكثر من الـ code-unit. مع العلم أن المساحات المستخدمه هى عدد البتات بكل من 1 و 2 و 4 بايت إلا أن إستخدام عدد البتات يرجع إلى أن العمليات فى كل ترميز تتم على مستوى البت. التصميم الأصلى لـ Unicode كان يحتوى على 65536 حرف داخل قاعدة بياناته، و عندما تم زيادة هذا المدى إلى 10FFFF16 حينها تم تسمية المدى الأصلي بالإسم Basic Multilingual Plane و إختصارا BMP، ذلك المدى يأخذ الترتيب صفر و يحتوى على أغلب حروف العالم، و باقي المساحه تم تقسيمها 16 جزء كل منهم بمساحة 65536 حرف و هم كالتالي[8]: Plane 0: Basic Multilingual Plane 0000-FFFFPlane 1: Supplementary Multilingual Plane 10000-1FFFFPlane 2: Supplementary Ideographic Plane 20000-2FFFFPlane 3-13: Unassigned 30000-DFFFFPlane 14: Supplementary Special-purpose Plane E0000-EFFFFPlane 15-16: Supplementary Private Use Area F0000-10FFFF      ترميز UTF-8 الهدف من وراء تصميم هذا الترميز[9] هو أن يكون بديل لـ ASCII، حيث من خلاله يمكن إستخدام ASCII و باقي حروف Unicode بدون مشاكل، هذا الترميز يستهلك 8 بت أو one-octet للـ code-unit الواحده و هو ديناميكي حيث عدد الـ code-unit المستخدم يكون فى المدى من 1-4 و ذلك حسب قيمة الـ code-point تبعا للجدول التالي:   +---------------------+-------------------------------------+| character code point| UTF-8 octet sequence |+---------------------+-------------------------------------+| 0000 0000-0000 007F | 0xxxxxxx |+---------------------+-------------------------------------+| 0000 0080-0000 07FF | 110xxxxx 10xxxxxx |+---------------------+-------------------------------------+| 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |+---------------------+-------------------------------------+| 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |+---------------------+-------------------------------------+من الجدول السابق تجد أنه إذا كان الحروف المستخدم فى المدى من 016 إلى 7F16 - و هو المدى الخاص بـ ASCII - فإن الحرف يتم ترميزه داخل code-unit واحده و عندما تكون قيمة الحرف فى المدى من 8016 إلى 10FFFF16 فإن البتات الخاصه بتلك القيمه يتم توزيعها بناءا على الجدول السابق و أن أول code-unit يحتوى داخل الـ Most significant bits الخاصه به على عدد code-units التى تمثل code-point فتجد ان المدى 8016-7FF16 أول بايت به يحتوى على 2 بت و هذا يعنى وجود two code-units و نفس الامر ينطبق على كل مدى تم تحديده بالجدول. عملية توزيع البتات الخاصه بالـ code point داخل Code Units لها ترتيب محدد و يتم كالتالي: قم بمعرفة عدد الـ Code Units التى تحتاجها لترميز الـ code point.قم بإعداد قيمة البتات الخاصه بالـ Code Units كما هو موجود بالجدول.داخل قيمة الـ Code point قم بأخذ البتات الموجوده بـ lowest-order و ضعها فى المكان المقابل لها داخل lowest-order bits الموجوده بأخر code unit و بعد ان تملء الـ code-unit قم بالذهاب للتي تسبقها مباشرة و قم بتكرار هذه العملية حتى تمتلء كافة الـ x.مثال الحرف "م" يأخذ القيمه U+0645 و لتحويلها لـ UTF-8 نعلم أن هذه القيمة تقع فى المدى الثاني و هذا يعنى أننا نحتاج two code units: 110xxxxx 10xxxxxxالخطوه التالية هي بتوزيع البتات الخاصه بقيمة الحرف و تتم كالتالي: 06 4500000110 01000101 -------> 110xxxxxx 1000010100000110 01 --- ---> 11011001 10000101D9 85كما ترى قيمة الحرف "م" داخل UTF-8 هى D916 8516. للتحويل من UTF-8 لقيمة الحرف code point نحتاج لمساحه أقصاها 21 بت (و هم عدد البتات التى يتم توزيعهم على كافة code units)، الخطوات تتم كالتالي: نقوم بحجز مساحه بحد أقصى 21 بت و نجعل قيمتهم صفر.نقوم بمعرفة عدد الـ code units التى تمثل الـ code point.نقوم بإستخلاص البتات من الـ code units من أقصي اليمين إلى اليسار و يتم و ضعهم داخل البتات (من الخطوه 1) بدءا من lowest-order bit و صلا لـ highest-order bit.الأن لنقوم بإستخلاص الـ code point من القيمه EF16 B716 BD16: EF B7 BD0xEF starts with 1110 which result 3 code-units which means we need 16-bits for target code-pointcp = 0000000000000000-> 11101111 10110111 10111101 ------cp = 0000000000111101 -------> 11101111 10110111 10111101 ------cp = 0000110111111101 -------> 11101111 10110111 10111101 ----cp = 1111110111111101 ----cp = 11111101 11111101 = FD FDالكود FDFD16 هو قيمة الحرف الذى يمثل البسلمة. عندما تكون الـ code units أكثر من واحده حينها تسمى الـ code-unit الأولي بالإسم lead-unit و الباقيين trail-unit و فى هذه الحالة توجد بعض الـ lead-unit التى إذا تم إستخدامها فهذا يعني invalid UTF-8 sequence و هم: C0, C1, F5-FFحيث الأولى و الثانية تسمح بتكويد code point فى المدى 0016-7F16 داخل وحدتين و الأكواد فى المدى F516-FF16 تسمح بتكويد code points فى مدى أكبر من 10FFFF16، أيضا الكود F416 يسمح بتكويد قيم أكبر من المدى المسموح به و لابد من التحقق من القيمه النهائية لتحديد إذا كانت صحيحه أو خاطئة. أحد المزايا الموجوده فى UTF-8 هو انه دائما يمكن معرفة بداية السلسلة و بالتالي إذا وجدت وحدة بداية بقيمه غير صحيحة يمكن بعدها تخطى البقية حتى الوصول لوحدة بداية أخرى (لاحظ ان الوحدات التى ليست بوحدات بداية تبدء دائما بـ 0b10).     ترميز UTF-16 عندما تم تصميم Unicode 1.0 تم إستخدام مساحة مقدارها 16 بت ليتم من خلالها ترميز كافة الحروف و سميت UCS-2، و مع الإصدار الثاني من Unicode تم توسيع مدى الاكواد و معه تم نبذ ذلك الترميز و تم إبتكار ترميز أخر[10] ليكون له بديلا. عند وضع تصميم Unicode 2.0 تم الأخذ فى الحسبان إمكانية إستخدام الترميز UTF-16 مع قيم أكبر من FFFF16، لهذا السبب و لجعل عملية ترميز أكواد الحروف من و إلى ذلك الترميز يسيرة تم حجز مساحه محدوده من أكواد الحروف ليتم إستخدامها بشكل خاص مع هذا الترميز للتعامل مع الحروف التى تحتاج مساحه أكبر من FFFF16. داخل UTF-16 أى code-point يمكن ترميزها داخل عدد two code-units بحد أقصى حيث إذا كانت قيمة الـ code-point أقل من أو تساوى FFFF16 حينها يتم حفظ قيمة الـ code-point داخل وحدة واحده - أى code-unit واحده - و إذا كانت قيمة الـ code-point أكبر من FFFF16 حينها يتم إستخدام وحدتان لترميز الـ code-point، هاتان الوحدتان يطلق على يطلق على الوحدة الأولي - التى توضع يسارا - الإسم High Surrogates، و يطلق على إسم الوحده الأخيره - التى توضع يمينا - الإسم Low Surrogates. بهذا أصبحت أكواد الحروف داخل Unicode تأخذ المساحات التالية: المدى 00DB7F16 - 00000016: يستخدم لتكويد الحروف.المدى 00DBFF16 - 00D80016: يستخدم مع ترميز UTF-16 فى مدى أكبر من FFFF16 داخل الوحده الأولى.المدى 00DFFF16 - 00DC0016: يستخدم مع ترميز UTF-16 فى مدى أكبر من FFFF16 داخل الوحده الأخيره.المدى 10FFFF16 - 00E00016: يستخدم لتكويد الحروف.لتحويل كود فى المدى من 10FFFF16 - 1FFFF16 نقوم بالأتي: يتم طرح القيمه 1000016 من قيمة الكود المدخل.القيمه الباقيه تتكون من 20 بت يتم تقسيمها إلى 10 بت و 10 بت.الـ 10 بت الموجودين على اليسار يتم إضافتهم على القيمه D80016 و القيمه الناتجه ستكون فى المدى من D80016 إلى DBFF16 و هذه قيمة الوحده الاولى.الـ 10 بت الموجودين على اليمين يتم إضافتهم على القيمه DC0016 و القيمه الناتجه ستكون فى المدى من DFFF16 إلى DC0016 و هذه قيمة الوحده الثانية.الخطوات بإسلوب أخر: If (Codepoint <= FFFF) return CodepointU = Codepoint - 10000U = xxxxxxxxxxyyyyyyyyyyA = xxxxxxxxxxB = yyyyyyyyyyCU1 = D800 + ACU2 = DC00 + Breturn CU1, CU2للحصول على قيمة الـ code-point من UTF-16 code-units: إذا كانت قيمة الوحده ليست فى المدى DFFF16 - D80016 حينها قيمة code-unit هى قيمة الـ code-point.إذا كانت قيمة الوحده الاولى ليست فى المدى DBFF16 - D80016 فالترميز خاطئ، و إذا كانت قيمة الوحدة الثانية ليست فى المدى DFFF16 - DC0016 فالترميز خاطئ.قم بطرح القيمه D80016 من الوحده الأولى و القيمه DC0016 من الوحده الثانية و قم بحجز مساحة 20 بت و ضع الناتج من الوحده الأولى فى الـ 10 بت الموجودين يسار الـ 20 بت و الناتج من الوحده الثانية فى الـ 10 بت الموجودين يمين الـ 20 بت.أضف القيمه 1000016 لقيمة الـ 20 بت و الناتج سيكون بحد أقصي 21 بت و هو قيمة الـ code-point.إذا كنت تتسائل لماذا تم تحديد القيمه 10FFFF16 لتكون أقصي قيمة لكود حرف فها هي الإجابه امامك، لأن حينها ستصبح الـ 20 بت تحتوى القيمة FFFFF16 و التى عندما يتم توزيعها ستعطينا الوحدتان DBFF-DFFF16. الإجابه بإسلوب أخر: أقصي قيمة يمكن ترميزها داخل UTF-16 هى القيمه 10FFFF16 و لهذا جعلت أقصى قيمة لأى كود داخل Unicode و Universal Character Set. عملية حفظ الـ 16 بت داخل الذاكره تختلف بإختلاف المعمارية المستخدمه حيث ترتيب الـ 2 بايت الممثلين للـ 16 بت يختلف بين Little-Endian و Big-Endian لذا إستخدام Byte Order Mark مع ترميز UTF-16 أمر أساسي     ترميز UTF-32 يمكنك اعتبار هذا الترميز أبسط ترميز حيث يستطيع تمثيل كافة أكواد Unicode داخل وحدة واحدة بمساحة 32 بت، و هذا يجعل عملية ربط قيمة الحرف و الكود لا تحتاج لأى عمليات. هذا الترميز قلما تجد المحررات أو البرامج تدعمه لأنه المساحه التى يستخدمها مكلفه جدا، و أغلب ما يتم إستخدامه داخليا فى البرامج التى تقوم بقراءة ملفات بصيغة Unicode مثل المترجمات (فى الغالب).     علامة BOM هى إختصار لـ Byte Order Mark و هى إسم للقيمة 0000FEFF32 و تستخدم كأول كود فى سلسلة أكواد بترميز محدد[11] لتقوم بتحديد الترميز المستخدم. UTF-8 عندما يتم إستخدام هذا الترميز فمن الأفضل عدم إستخدام BOM لأن هذا الترميز تم تصميمه ليحوى ASCII بالإضافه لباقي أكواد Unicode و إستخدامك للـ BOM سيجعل البرامج القديمه (desktop - web) تحتاج للتعديل و هذا قد يكون غير متاح، بالإضافه إلى انه إذا تم تمرير سلسلة من الأكواد بهذا الترميز لأى برنامج يدعم UTF-8 فسيستطيع التعرف عليه مباشرة لأن هذا الترميز يسهل التعرف على وحداته بسهوله كما ذكر من قبل. و لكن إذا دعت الحاجه لوجود BOM حينها سيتم تحويل الكود المذكور لـ UTF-8 ليصبح EF BB BF، لاحظ ان هذا الترميز مبني على وحدة مساحتها 8 بت و لهذا فمشاكل ترتيب الوحدات Endianness غير موجوده بهذا الترميز.UTF-16 الوحده الواحدة داخل هذا الترميز تحفظ داخل وحدتين بمساحة 8 بت لكل منهم، و هنا تظهر مشكلة ترتيب الوحدات عند قراءة سلسلة أكواد لأنك إن حفظتهم من ألة تعمل بنمط Big-Endian فإنك لابد من أن تقرأهم بهذا النمط بغض النظر عن طبيعة الأله التى تقوم بالقرأه منها. حل هذه المشكلة يتم بوضع القيمه FEFF16 بأى سلسلة يتم حفظها بهذا الترميز، و عندما تكون السلسلة بنمط Big-Endian فترتيب وحدات هذه القيمه سيكون FE FF - تقرأ من اليسار لليمين - و عندما تكون السلسلة بنمط Little-Endian فترتيب وحدات هذه القيمه سيكون FF FE - تقرأ من اليسار لليمين - و السؤال الذى يتبادر إلى الذهن هو: ماذا يحدث إذا تم حفظ السلسلة من BE و تم قرائتها من LE بترتيب وحدات LE؟ فى هذه الحالة القيمه التى سيتم قرائتها هى FFFE16 و هى تقابل حرف من الحروف الممنوع إستخدامها فى تبادل المعلومات و ايضا احد اوصافه هو انه يمكن استخدامه لمعرفة ترتيب الوحدات مع FEFF16، و هذا يعنى ايا كان الأله التى تقرأ منها فإنه يوجد لديك إحتمالين و هم قراءة FEFF16 أو FFFE16 و إحداهما تدل على ان السلسلة بترميز LE و الأخرى تدل على ان السلسلة بترميز BE.UTF-32 بالمثل مع UTF-16 و لكن فى هذه الحالة سيتم كتابة الأصفار، و بالتالي عند كتابة BOM بنمط Little-Endian فترتيب الأكواد سيكون FF FE 00 00 - تقرأ من اليسار لليمين - و عندما يكون النمط Big-Endian فترتيب الأكواد سيكون 00 00 FE FF - تقرأ من اليمين لليسار.مكتبة charset مكتبة charset قمت بكتابتها بلغة ++C و لها ثلاثة إستخدامات: التحويل code-unit بين من ترميز لأخر.تحويل حرف من character-set إلى Unicode و العكس.تحويل stream كاملة من character-set إلى Unicode و العكس.تحويل stream كامله من character-set لأخرى أو من ترميز Unicode لترميز Unicode أخر.لا يمكن القول على هذه المكتبه انها تدعم Unicode بشكل كامل حيث هذا التعريف يشمل إمكانية تحديد خصائص الحروف مثل حالو الحرف و نوعه و تحويله من حالة لأخرى و غيرها من الخصائص، و لكن يمكنك إعتبار هذه المكتبه كأداة يسيرة يمكن إستخدامها للتحويل من ترميز لأخر.     خاتمة تعرفنا فى هذه المقالة عن الطرق الأوليه فى تبادل البيانات من شفرة موريس إلى شفرة ميوراى إلى ASCII و من ثم ظهور الألات التى تستهلك 8 بت بدلا من 7 بت و معهم ظهور مفهوم صفحة المحارف الواحده و المتعدده و من بعدهم تم جمع محاسن كل هذه الأفكار فى منظومة جيده محدوده المعالم أظهترها Unicode للعالم فى شكل أفكار محدده تم تطبيقها ليظهر لنا أكثر من ترميز للتعامل مع البيانات. قليل ما ذكرته فى هذه المقالة و كثير ما بقي لك لتستكشفه بنفسك و أول خطواتك فى هذا الطريق هي بتحميل الإصدار الأخير من Unicode و القراءه منه و بعدها تحميل اى مكتبه تدعم Unicode للغتك و ابدء بالتطبيق. و الله ولي التوفيق [1]مع العلم أن عنوان الموضوع هو ترميز الحروف إلا أن الهدف منه هو تعريفك بترميز Unicode و كيفية إستخدامه و الإستفاده منه و لهذا سيتم إهمال العديد من الاحداث التاريخية و ذكر أخرين بشكل مجمل حتى لا نقوم بالتركيز على نقاط جانبية اكثر مما ينبغي. [2]هذا السلوك موجود حتى يومنا هذا فى مكتبة الإدخال و الإخراج بلغة السي و يعتبر هو السلوك الإفتراضي حيث لا يتم حفظ المحتويات التى يتم كتابتها داخل stream إلا بعد كتابة علامة السطر الجديد. [3]مع العلم انه تم رفض الكود shift إلا أن بعض المنشئات قامت بتصميم ترميز خاص بها و أستخدمته و لكن ليس لقترة طويلة. [4]راجع جزء ASCII Control characters من مقال Wikipedia. [5]بالإضافة إلى أن IBM هى أول من صنع أجهزة بمعالجات 8 بت فإنها أيضا أول من طبق مفهوم Byte Address بدلا من Bit Address (و يعنى التعامل مع الذاكرة على مستوى البت). [6]المصطلح Code Page يقابل الكلمه صفحة محارف باللغه العربية. [7]يمكنك معرفة كافة هذه الإختلافات من Appendix C بتوثيق Unicode أو بعضها من Wikipedia. [8]يمكنك معرفة تفاصيل أكثر عن هذه المساحات و طبيعة محتواها من Wikipedia أو من توثيق Unicode أو من توثيق ISO. [9]راجع المقالة التى تتحدث عن UTF-8 داخل Wikipedia، أو أقرأ عن هذا الترميز بالتفصيل فى وثيقة من RFC. [10]راجع المقالة التى تتحدث عن UTF-16 داخل Wikipedia، أو أقرأ عن هذا الترميز بالتفصيل فى وثيقة من RFC. [11]يوجد أكثر من ترميز غير المذكورين هنا و لكنهم غير مدعومين من Unicode.
  2. السلام عليكم اختي والحمد لله على عودة المنتدى الغالي. أنا أستعمل أكسس 2003 النسخة الفرنسية. عندما أحمّل ملفات من المنتدى وكلها تحتوي حتما على اللغة العربية إما داخل الأكواد أو كأسماء لعناصر التحكم. أجد نفسي مضطرا ( في كل مرة أود فيها فتح هذه الملفات ) لأن أتحقق من كون الخيار " لغة البرامج non unicode " على اللغة العربية، ثم اعادة تشغيل الجهاز. طبعا هذا الخيار موجود في المسار التالي: لوحة التحكم / الخيارات الاقليمية و خيارات اللغة / خيارات متقدمة / لغة للبرامج بدون unicode. وإن تركت هذا الخيار على اللغة الفرنسية ( لاننا في الجزائر نستعمل البرامج باللغة الفرنسية وهي في الغالب لن تعمل إلا على خيار اللغة الفرنسية ) فلن يفتح الملف بشكل طبيعي وتظهر رسالة الخطأ التالية: والتي ترجمتها كما يلي: العبارة On Activation المدخلة كوسيط للخاصية من نوع حدث هي مصدر لخطأ. حدثت مشكلة أثناء الاتصال بين microsoft office access و الخادم OLE أو عنصر التحكم ActiveX. أريد حلا لهذه المشكلة: ـ ربما كود يقوم بتغيير خيار لغة البرامج non unicode الى العربية تلقائيا بمجرد فتح الملف ويغنينا عن القيام بذللك يدويا وعن اعادة التشغيل. ـ ربما اضافة ما تضاف الى الملف بحيث يمكن فتحه بأي نسخة من أكسس مهما كانت لغتها و مهما كانت خيارات اللغة. ـ ربما ... ارجو ان تكون المشكلة واضحة، عذرا على الاطالة و شكرا مسبقا.
  3. عند التعامل مع النصوص العربية باستخدام لغة vb.net  فقد واجهتي مشكلة رقم اليوني كود الخاص باحرف اللغة العربية حيث مثلا كلمة (ههه ) كل حرف من هذه الاحرف له رقم كود معين بجدول اليوني كود ولكن عند استخدام chrw  على اي حرف من هذه الحرف نجد ان الكود الناتج من هذه الدالة هو نفس الكود لجميع الحروف . وبعد ان قمت بالبحث عن الحل في الانترنت فقد وجدت ان التعامل مع اللغة العربية يتم بطريقة ايجاد ال glyph الخاص لكل حرف باستخدام api من uniscript وتحديدا استخدام SCRIPT_ANALYSIS Structure  من ذلك والموقع الذي يتحدث عن هذا الموضوع هو http://msdn.microsoft.com/en-us/library/dd374093.aspx من شكة مايكروسوفت   كيف يمكن كتابة ال  api  الخاصة بذلك بالاعتماد على uniscript function apis و باستخدام vb.net وهل هنلك طريقة اخرى بحيث نرسل النص العربي لدالة معينة function  وتقوم هذه الدالة بارجاع الكود الخاص (يوني كود) الفعلي لكل حرف في جملة معينة  مع العلم ان كلمة (ههه) كود الهاء في اول الكلمة FEEB    هـ‎ كود الهاء في وسط الكلمة FEEC    ـهـ‎ كود الهاء في اخر الكلمة متصل FEEA ـه‎ عند استخدام الاوامر التاية يظهر 0647 دائما وهو الكود  General Unicode (هـ‎)  كل حرف في اللغة العربية له اربعة اكواد في اليوني كود حسب موقعة في الكلمة (Isolated,End,Middle,Beginning)  الذي يظهر دائما باستخدام الكود في الاسفل هو General Unicode    s = "ههه"        Dim enc As System.Text.Encoding = System.Text.Encoding.Unicode         Dim arr1 As Byte() = enc.GetBytes(s) ارجو المساعدة في استخراج الكود الفعليوجزاكم الله الشكر والعافية وتقب الله طاعاتكم في هذا اليوم المبارك وهو الجمعة