কম্পিউটার

রুবিতে ইউনিকোড স্বাভাবিককরণ

আমি সম্প্রতি একটি নিবন্ধ প্রকাশ করেছি যাতে আমি রুবির বেশিরভাগ স্ট্রিং পদ্ধতিগুলি নির্দিষ্ট ইউনিকোড অক্ষরগুলির সাথে পরীক্ষা করে দেখেছি যে তারা অপ্রত্যাশিতভাবে আচরণ করবে কিনা। তাদের অনেকেই করেছে।

নিবন্ধটির কিছু লোকের একটি সমালোচনা ছিল যে আমি পরীক্ষার জন্য অস্বাভাবিক স্ট্রিং ব্যবহার করছিলাম। সত্যি বলতে কি, আমি ইউনিকোড স্বাভাবিকীকরণে কিছুটা অস্পষ্ট ছিলাম। আমি সন্দেহ করি যে অনেক রুবিস্ট।

স্বাভাবিককরণ ব্যবহার করে, আপনি অনেক ইউনিকোড স্ট্রিং নিতে পারেন যা আমার পরীক্ষায় অপ্রত্যাশিতভাবে আচরণ করেছে এবং সেগুলিকে স্ট্রিংগুলিতে রূপান্তর করতে পারে যা রুবির স্ট্রিং পদ্ধতির সাথে ভাল খেলতে পারে। যাইহোক:

  1. রূপান্তর সবসময় নিখুঁত হয় না। কিছু ইউনিকোড ক্রম সর্বদা রুবির স্ট্রিং পদ্ধতিগুলিকে খারাপ আচরণের কারণ হবে৷
  2. এটি এমন কিছু যা আপনাকে ম্যানুয়ালি করতে হবে৷ রুবি, না রেল বা ডিবি ডিফল্টরূপে স্বয়ংক্রিয়ভাবে স্বাভাবিক হয় না৷

এই নিবন্ধটি রুবিতে ইউনিকোড স্বাভাবিককরণের একটি সংক্ষিপ্ত ভূমিকা হবে। আশা করি এটি আপনাকে আপনার নিজস্ব অনুসন্ধানের জন্য একটি জাম্পিং-অফ পয়েন্ট দেবে৷

আসুন একটি স্ট্রিং স্বাভাবিক করা যাক

String#unicode_normalize রুবি 2.2 এ পদ্ধতি চালু করা হয়েছিল। রুবিতে লেখা হওয়ায়, এটি utf8_proc এবং ইউনিকোড রত্নগুলির মতো স্বাভাবিকীকরণ লাইব্রেরির মতো দ্রুত নয় যা C লিভারেজ করে।

আমাদের স্বাভাবিককরণের প্রয়োজনের কারণ হল যে ইউনিকোডে একটি অক্ষর লেখার একাধিক উপায় রয়েছে। অক্ষর "Å" কোড পয়েন্ট "\u00c5" হিসাবে উপস্থাপন করা যেতে পারে অথবা অক্ষর "A" এবং একটি উচ্চারণের রচনা হিসাবে:"A\u030A" .

রুবিতে ইউনিকোড স্বাভাবিককরণ

সাধারণীকরণ একটি ফর্মকে অন্য ফর্মে রূপান্তর করে:

"A\u030A".unicode_normalize        #=> 'Å' (same as "\u00C5")

অবশ্যই, ইউনিকোডকে স্বাভাবিক করার একমাত্র উপায় নেই। যে খুব সহজ হবে! স্বাভাবিককরণের চারটি উপায় আছে, যাকে "স্বাভাবিককরণ ফর্ম" বলা হয়। ক্রিপ্টিক সংক্ষিপ্ত শব্দ ব্যবহার করে তাদের নামকরণ করা হয়েছে:NFD, NFC, NFKD এবং NFKC।

String#unicode_normalize ডিফল্টরূপে এনএফসি ব্যবহার করে, কিন্তু আমরা একে অন্য ফর্ম ব্যবহার করতে বলতে পারি:

"a\u0300".unicode_normalize(:nfkc)       #=> 'à' (same as "\u00E0")

কিন্তু এই আসলে কি মানে? চারটি স্বাভাবিকীকরণ ফর্ম আসলে কি করে? চলুন দেখে নেওয়া যাক।

সাধারণকরণ ফর্ম

দুই ধরনের স্বাভাবিকীকরণ অপারেশন আছে:

  • কম্পোজিশন: বহু-কোড-পয়েন্ট অক্ষরকে একক কোড পয়েন্টে রূপান্তর করে। যেমন:"a\u0300" "\u00E0" হয়ে যায় , উভয়ই à অক্ষর এনকোড করার উপায় .
  • পচন: রচনার বিপরীত। একক-কোড-পয়েন্ট অক্ষরকে একাধিক কোড পয়েন্টে রূপান্তর করে। যেমন:"\u00E0" "a\u0300" হয়ে যায় .

রচনা এবং পচন প্রতিটি দুটি উপায়ে করা যেতে পারে:

  • প্রামানিক: গ্লিফ সংরক্ষণ করে। উদাহরণের জন্য:"2⁵" "2⁵" থেকে যায় যদিও কিছু সিস্টেম সুপারস্ক্রিপ্ট-ফাইভ অক্ষর সমর্থন নাও করতে পারে।
  • সামঞ্জস্যতা: গ্লিফগুলিকে তাদের সামঞ্জস্যপূর্ণ অক্ষর দিয়ে প্রতিস্থাপন করতে পারে। যেমন:"2⁵" "2 5"-এ রূপান্তরিত হবে .

দুটি ক্রিয়াকলাপ এবং দুটি বিকল্প চারটি "স্বাভাবিককরণ ফর্ম" তৈরি করতে বিভিন্ন উপায়ে একত্রিত হয়। ইনপুট এবং আউটপুটের বিবরণ এবং উদাহরণ সহ আমি সেগুলি নীচের সারণীতে তালিকাভুক্ত করেছি:

নাম বিবরণ ইনপুট আউটপুট
NFD ক্যাননিকাল পচন Å "\u00c5" Å "A\u030A"
NFC ক্যাননিকাল কম্পোজিশন অনুসরণ করে ক্যানোনিকাল কম্পোজিশন Å "A\u030A" Å "\u00c5"
NFKD সামঞ্জস্যতা পচন ẛ̣ "\u1e9b\u0323" "\u0073\u0323\u0307"
NFKC ক্যানোনিকাল কম্পোজিশন দ্বারা অনুসরণ করা সামঞ্জস্যতা পচন ẛ̣ "\u1e9b\u0323" "\u1e69"

আপনি যদি এই টেবিলটি কয়েক মিনিটের জন্য দেখেন তবে আপনি লক্ষ্য করতে শুরু করতে পারেন যে সংক্ষিপ্ত শব্দগুলি অর্থপূর্ণ হয়:

  • "NF" মানে "নর্মালাইজেশন ফর্ম।"
  • "D" এর অর্থ হল "decomposition"
  • "C" মানে "কম্পোজিশন"
  • "K" মানে "কম্প্যাটিবিলিটি" :)

আরও উদাহরণের জন্য এবং আরও পুঙ্খানুপুঙ্খ প্রযুক্তিগত ব্যাখ্যার জন্য, ইউনিকোড স্ট্যান্ডার্ড অ্যানেক্স #15 দেখুন।

একটি স্বাভাবিকীকরণ ফর্ম নির্বাচন করা

আপনার যে স্বাভাবিকীকরণ ফর্মটি ব্যবহার করা উচিত তা হাতের কাজের উপর নির্ভর করে। নীচের আমার সুপারিশগুলি ইউনিকোড স্বাভাবিককরণ FAQ-এর উপর ভিত্তি করে৷

স্ট্রিং সামঞ্জস্যের জন্য NFC ব্যবহার করুন

আপনার লক্ষ্য যদি রুবির স্ট্রিং পদ্ধতিগুলিকে বেশিরভাগ ইউনিকোডের সাথে সুন্দরভাবে চালানো হয়, আপনি সম্ভবত NFC ব্যবহার করতে চান। String#unicode_normalize এর জন্য এটি ডিফল্ট হওয়ার একটি কারণ আছে .

  • এটি যেখানে সম্ভব সেখানে একাধিক-কোড-পয়েন্ট অক্ষরকে একক কোড পয়েন্টে কম্পোজ করে। মাল্টি-কোড-পয়েন্ট অক্ষরগুলি স্ট্রিং পদ্ধতিতে বেশিরভাগ সমস্যার উত্স।
  • এটি গ্লিফগুলিকে পরিবর্তন করে না, তাই আপনার শেষ-ব্যবহারকারীরা তাদের ইনপুট করা পাঠ্যের কোনো পরিবর্তন লক্ষ্য করবেন না৷

এটি বলেছিল, সমস্ত মাল্টি-কোড-পয়েন্ট অক্ষর একটি একক কোড পয়েন্টে তৈরি করা যায় না। এই ক্ষেত্রে রুবির স্ট্রিং পদ্ধতিগুলি খারাপ আচরণ করবে:

s = "\u01B5\u0327\u0308"          # => "Ƶ̧̈", an un-composable character
s.unicode_normalize(:nfc).size    # => 3, even though there's only one character

নিরাপত্তা এবং DB সামঞ্জস্যের জন্য NFKC ব্যবহার করুন

আপনি যদি নিরাপত্তা-সম্পর্কিত পাঠ্যের সাথে কাজ করেন যেমন ব্যবহারকারীর নাম, বা প্রাথমিকভাবে আপনার ডাটাবেসের সাথে সুন্দরভাবে পাঠ্য চালাতে আগ্রহী, তাহলে NFKC সম্ভবত একটি ভাল পছন্দ।

  • এটি সম্ভাব্য সমস্যাযুক্ত অক্ষরকে তাদের সামঞ্জস্যপূর্ণ অক্ষরে রূপান্তর করে।
  • এটি তারপর সমস্ত অক্ষরকে একক কোড পয়েন্টে কম্পোজ করে।

কেন এটি নিরাপত্তার জন্য উপযোগী তা দেখতে, কল্পনা করুন যে আপনার ব্যবহারকারীর নাম "HenryIV" আছে। একটি দূষিত অভিনেতা একটি নতুন ব্যবহারকারীর নাম নিবন্ধন করে এই ব্যবহারকারীর ছদ্মবেশী করার চেষ্টা করতে পারে:"HenryⅣ"।

আমি জানি, তারা একই চেহারা. এটাই আসল কথা. কিন্তু তারা আসলে দুটি ভিন্ন স্ট্রিং. আগেরটি ascii অক্ষর "IV" ব্যবহার করে যখন পরবর্তীটি রোমান সংখ্যা 4-এর জন্য ইউনিকোড অক্ষর ব্যবহার করে:"Ⅳ" .

আপনি স্বতন্ত্রতা যাচাই করার আগে স্ট্রিংগুলিকে স্বাভাবিক করার জন্য NFKC ব্যবহার করে এই ধরণের জিনিস প্রতিরোধ করতে পারেন। এই ক্ষেত্রে, NFKC ইউনিকোডকে রূপান্তর করে "\u2163" ascii অক্ষরে "IV"।

a = "Henry\u2163"
b = "HenryIV"
a.unicode_normalize(:nfc) == b.unicode_normalize(:nfc) # => false, because NFC preserves glyphs
a.unicode_normalize(:nfkc) == b.unicode_normalize(:nfkc) # => true, because NFKC evaluates both to the ascii "IV"

পার্টিং শব্দ

এখন যেহেতু আমি এটিকে আরও বেশি করে দেখেছি, আমি একটু অবাক হয়েছি যে ইউনিকোড স্বাভাবিকীকরণ রুবি এবং রেল সম্প্রদায়ের মধ্যে একটি বড় বিষয় নয়। আপনি আশা করতে পারেন যে এটি আপনার জন্য রেল দ্বারা করা হবে, কিন্তু যতদূর আমি বলতে পারি তা নয়। এবং আপনার ব্যবহারকারীরা আপনাকে যে ডেটা দেয় তা স্বাভাবিক না করার অর্থ হল রুবির অনেক স্ট্রিং পদ্ধতি নির্ভরযোগ্য নয়৷

যদি আপনার প্রিয় পাঠকদের মধ্যে কেউ এমন কিছু জানেন যা আমি জানি না, অনুগ্রহ করে টুইটার @StarrHorne বা starr@honeybadger.io-এ ইমেলের মাধ্যমে যোগাযোগ করুন। ইউনিকোড একটি বড় বিষয় এবং আমি ইতিমধ্যে প্রমাণ করেছি যে আমি এটি সম্পর্কে সবকিছু জানি না। :)


  1. রুবিতে বিটওয়াইজ হ্যাক

  2. রুবিতে ল্যাম্বডাস ব্যবহার করা

  3. রুবিতে সন্নিবেশ বাছাই বোঝা

  4. রুবি 2.6-এ 9টি নতুন বৈশিষ্ট্য