ম্যাকরোমান, সিপি 1252, ল্যাটিন 1, ইউটিএফ -8 এবং এএসসিআইআইয়ের মধ্যে কীভাবে নির্ভরযোগ্যভাবে এনকোডিং অনুমান করা যায়


99

কর্মক্ষেত্রে দেখে মনে হয় কোনও এনকোডিং-সম্পর্কিত সংযোগ, বিপর্যয় বা বিপর্যয় ছাড়াই কোনও সপ্তাহ কাটে না। সমস্যাটি সাধারণত প্রোগ্রামারদের কাছ থেকে আসে যারা মনে করেন যে তারা এনকোডিং নির্দিষ্ট না করেই কোনও "পাঠ্য" ফাইলটি নির্ভরযোগ্যভাবে প্রক্রিয়া করতে পারে। কিন্তু আপনি পারবেন না।

সুতরাং এখন থেকে ফাইলগুলির নাম *.txtবা নাম শেষ হওয়া থেকে নিষেধ করার সিদ্ধান্ত নেওয়া হয়েছে *.text। চিন্তাভাবনাটি হ'ল এই এক্সটেনশানগুলি এনকোডিংগুলি সম্পর্কে নৈমিত্তিক প্রোগ্রামারকে নৈমিত্তিক প্রোগ্রামারকে বিভ্রান্ত করে এবং এর ফলে সঠিকভাবে পরিচালনা করা যায় না। মোটেও কোনও এক্সটেনশান না করাই প্রায় ভাল, কারণ কমপক্ষে তখন আপনি জানেন যে আপনি কী পেয়েছেন তা আপনি জানেন না।

তবে আমরা এতদূর যেতে চাই না go পরিবর্তে আপনি এমন একটি ফাইল নাম ব্যবহার করবেন যা এনকোডিংয়ে শেষ হবে expected টেক্সট ফাইলে সুতরাং, উদাহরণস্বরূপ, এইসব ভালো কিছু হবে README.ascii, README.latin1, README.utf8, ইত্যাদি

কোনও নির্দিষ্ট বর্ধনের দাবি করা ফাইলগুলির জন্য, যদি কেউ ফাইলের মধ্যেই এনকোডিং নির্দিষ্ট করতে পারে যেমন পার্ল বা পাইথন-তে, তবে আপনি এটি করতে পারেন। জাভা উত্সের মতো ফাইলগুলির জন্য যেখানে ফাইলের অভ্যন্তরীণ কোনও সুবিধা নেই, আপনি এক্সটেনশনের আগে এনকোডিং রাখবেন, যেমন SomeClass-utf8.java

আউটপুট জন্য, UTF-8 দৃ strongly ়ভাবে পছন্দ করা উচিত।

তবে ইনপুটটির জন্য, আমাদের কোডবেজে থাকা হাজার হাজার ফাইলকে কীভাবে মোকাবেলা করতে হবে তা খুঁজে বের করতে হবে *.txt। আমাদের নতুন স্ট্যান্ডার্ডের সাথে ফিট করার জন্য আমরা তাদের সকলের নাম পরিবর্তন করতে চাই। তবে আমরা সম্ভবত তাদের সবাইকে চোখের জল ফেলতে পারি না। সুতরাং আমাদের দরকার এমন একটি লাইব্রেরি বা প্রোগ্রাম যা আসলে কাজ করে।

এগুলি এএসসিআইআই, আইএসও -8859-1, ইউটিএফ -8, মাইক্রোসফ্ট সিপি 1252 বা অ্যাপল ম্যাকরোম্যানে বিভিন্নভাবে রয়েছে। যদিও আমরা জানি যে আমরা কিছু ASCII কিনা তা বলতে পারি, এবং আমরা সম্ভবত কিছুটা UTF-8 কিনা তা জানার একটি ভাল পরিবর্তন করেছি, আমরা 8-বিট এনকোডিংগুলি সম্পর্কে স্টাম্পড করেছি। যেহেতু আমরা বেশিরভাগ ডেস্কটপ ম্যাক হওয়ায় একটি মিশ্র ইউনিক্স পরিবেশে (সোলারিস, লিনাক্স, ডারউইন) চালাচ্ছি, আমাদের কাছে বেশ কয়েকটি বিরক্তিকর ম্যাক্রোম্যান ফাইল রয়েছে। এবং এগুলি বিশেষত একটি সমস্যা।

কিছু সময়ের জন্য আমি প্রোগ্রামভিত্তিক কোনটি নির্ধারণের জন্য একটি উপায় সন্ধান করছি

  1. এএসসিআইআই
  2. আইএসও -8859-1
  3. সিপি 1252
  4. ম্যাক্রোম্যান
  5. ইউটিএফ -8

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

সুতরাং আমি যা খুঁজছি তা একটি বিদ্যমান লাইব্রেরি বা প্রোগ্রাম যা নির্ভরযোগ্যভাবে নির্ধারণ করে যে কোনও পাঁচটি এনকোডিংয়ের মধ্যে কোনটি ফাইলের মধ্যে রয়েছে pre এবং তার চেয়ে বেশি তার চেয়ে বেশি। বিশেষত এটির তিনটি বিট এনকোডিংয়ের মধ্যে পার্থক্য করতে হবে যা আমি উদ্ধৃত করেছি, বিশেষত ম্যাকরোম্যান । ফাইলগুলি 99% এরও বেশি ইংরেজি ভাষার পাঠ্য; অন্যান্য ভাষায় কয়েকটি রয়েছে তবে অনেকগুলি নয়।

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

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

এবং হ্যাঁ, আমি সম্পূর্ণরূপে বুঝতে পারি যে কেউ কেন সমস্যার প্রকৃতি বিবেচনা করে একটি নির্দিষ্ট উত্তরের গ্যারান্টি দিতে পারে না। এটি বিশেষত ছোট ফাইলগুলির ক্ষেত্রে, যেখানে আপনার কাছে পর্যাপ্ত ডেটা নেই। ভাগ্যক্রমে, আমাদের ফাইলগুলি খুব কমই ছোট। এলোমেলো READMEফাইল ছাড়াও বেশিরভাগগুলি 50k থেকে 250k আকারের হয় এবং অনেকগুলিই এর চেয়ে বড়। আকারে কয়েক কে-এর চেয়ে বেশি যে কোনও কিছু ইংরাজীতে থাকার গ্যারান্টিযুক্ত।

সমস্যা ডোমেনটি বায়োমেডিকাল পাঠ্য মাইনিং, তাই আমরা কখনও কখনও PubMedCentral এর ওপেন অ্যাক্সেস রিসোসিটোরির মতো সমস্ত বিস্তৃত এবং অত্যন্ত বৃহত কর্পোরার সাথে ডিল করি। বরং একটি বিশাল ফাইলটি হ'ল বায়োথেসরাস us.০, 7. 5. গিগাবাইটে। এই ফাইলটি বিশেষত বিরক্তিকর কারণ এটি প্রায় সমস্ত ইউটিএফ -8। তবে কিছু নাম্বস্কুল গিয়েছিল এবং এতে কয়েকটি লাইন আটকেছিল যা কিছু 8-বিট এনকোডিং-মাইক্রোসফ্ট সিপি 1252-এ রয়েছে, আমি বিশ্বাস করি। আপনি এটিতে ভ্রমণের আগে এটি বেশ খানিকটা সময় নেয়। :(


দেখুন stackoverflow.com/questions/4255305/... একটি সমাধান জন্য
mpenkov

উত্তর:


86

প্রথমত, সহজ কেস:

এএসসিআইআই

যদি আপনার ডেটাতে 0x7F এর উপরে কোনও বাইট না থাকে তবে এটি ASCII। (বা একটি 7-বিট ISO646 এনকোডিং, তবে সেগুলি খুব অপ্রচলিত)

ইউটিএফ -8

যদি আপনার ডেটা যাচাই হল UTF-8 যেমন, তাহলে আপনি নিরাপদে অনুমান করতে পারেন এটা হয় হল UTF-8। ইউটিএফ -8 এর কঠোর বৈধতা নিয়মের কারণে, মিথ্যা ধনাত্মকতা অত্যন্ত বিরল।

আইএসও -8859-1 বনাম উইন্ডোজ-1252

এই দুটি এনকোডিংয়ের মধ্যে একমাত্র পার্থক্য হ'ল আইএসও -8859-1 এর সি 1 নিয়ন্ত্রণ অক্ষর রয়েছে যেখানে উইন্ডোজ -1222-এ মুদ্রণযোগ্য অক্ষর রয়েছে € ‚ƒ„… † ‡ ˆ ‰ Š ‹ŒŽ ''" "• –—˜ ™ š› । আমি প্রচুর ফাইল দেখেছি যা কোঁকড়ানো উদ্ধৃতি বা ড্যাশ ব্যবহার করে তবে C1 নিয়ন্ত্রণের অক্ষর ব্যবহার করে না none সুতরাং তাদের সাথে বা আইএসও -8859-1 নিয়েও বিরক্ত করবেন না, কেবল তার পরিবর্তে উইন্ডোজ -1222 সনাক্ত করুন।

এটি এখন আপনাকে কেবল একটি প্রশ্ন রেখে দেয়।

আপনি সিপি 1252 থেকে ম্যাকরোমনকে কীভাবে আলাদা করতে পারেন?

এটি অনেক চালাকি।

অপরিবর্তিত অক্ষর

উইন্ডোজ -১২২২ এ 0x81, 0x8D, 0x8F, 0x90, 0x9D ব্যবহার করা হয় না। যদি সেগুলি ঘটে থাকে তবে ধরে নিই ডেটা ম্যাকরোম্যান।

স্বতন্ত্র অক্ষর

উভয় এনকোডিংয়ে বাইটস 0xA2 (¢), 0xA3 (£), 0xA9 (©), 0xB1 (±), 0xB5 (µ) হয়। এগুলি যদি কেবলমাত্র ASCII বাইট হয় তবে আপনি ম্যাকরোমন বা সিপি 1252 নির্বাচন করেছেন কিনা তা বিবেচ্য নয়।

পরিসংখ্যান পদ্ধতির

আপনি ইউটিএফ -8 হতে জানেন এমন ডেটাতে অক্ষর (বাইট না!) ফ্রিকোয়েন্সি গণনা করুন। সর্বাধিক ঘন অক্ষরগুলি নির্ধারণ করুন। তারপরে সিপি 1252 বা ম্যাকরোমান অক্ষরগুলি বেশি সাধারণ কিনা তা নির্ধারণ করতে এই ডেটাটি ব্যবহার করুন।

উদাহরণস্বরূপ, একটি অনুসন্ধানে আমি 100 টি এলোমেলো ইংলিশ উইকিপিডিয়া নিবন্ধগুলিতে সম্পাদন করেছি, সর্বাধিক সাধারণ নন-এএসসিআইআই অক্ষর ·•–é°®’èö—। এই সত্যের উপর ভিত্তি করে,

  • বাইটস 0x92, 0x95, 0x96, 0x97, 0xAE, 0xB0, 0xB7, 0xE8, 0xE9, বা 0xF6 উইন্ডোজ -1222 এর পরামর্শ দেয়।
  • বাইটস 0x8E, 0x8F, 0x9A, 0xA1, 0xA5, 0xA8, 0xD0, 0xD1, 0xD5, বা 0xE1 ম্যাকরোমনের পরামর্শ দেয়।

সিপি 1252-প্রস্তাবিত বাইট এবং ম্যাকরোমন-প্রস্তাবিত বাইটগুলি গণনা করুন এবং যে কোনওটি সবচেয়ে ভাল with


6
আমি আপনার উত্তরটি গ্রহণ করেছি কারণ এর চেয়ে ভাল আর কেউ উপস্থাপন করেনি এবং আমি যে বিষয়গুলির সাথে ঝুঁকির মধ্যে পড়েছিলাম সেগুলি লিখে আপনি ভাল কাজ করেছেন। আমার কাছে সত্যিই সেই বাইটগুলি স্নিগ্ধ করার জন্য প্রোগ্রাম রয়েছে, যদিও আমি নিজেই যে সংখ্যাটি নিয়ে এসেছি তার দ্বিগুণ।
tchrist

10
অবশেষে এটি বাস্তবায়নের প্রায় কাছাকাছি। দেখা যাচ্ছে উইকিপিডিয়া ভাল প্রশিক্ষণের ডেটা নয়। 1k র্যান্ডম এন.ইউইকিপিডিয়া নিবন্ধগুলি থেকে, ভাষাগুলির অংশটি গণনা করা হচ্ছে না, আমি 50 কে ইউএনএসসিআইআই কোডপয়েন্ট পেয়েছি, তবে বিতরণটি বিশ্বাসযোগ্য নয়: মাঝারি ডট এবং বুলেট খুব বেশি, & সি & সি & সি; সুতরাং আমি অল-ইউটিএফ 8 পাবমেড ওপেন অ্যাক্সেস কর্পস, মাইনিং + 14 এম ইউএনএসসিআইআই কোডপয়েন্ট ব্যবহার করেছি। আমি আপনার 8 টি-বিট এনকোডিংগুলির আপেক্ষিক-ফ্রিকোয়েন্সি মডেলটি তৈরি করতে এটি ব্যবহার করি যা আপনার চেয়ে কল্পিত তবে সেই ধারণার ভিত্তিতে। এটি বায়োমেডিকাল পাঠ্য, লক্ষ্য ডোমেনের জন্য এনকোডিংয়ের অত্যন্ত অনুমানযোগ্য প্রমাণ করে । আমার এটি প্রকাশ করা উচিত। ধন্যবাদ!
tchrist

5
আমার কাছে এখনও কোনও ম্যাকরোম্যান ফাইল নেই, তবে লাইন ডিলিমিটারগুলি দরকারী পরীক্ষার হিসাবে সিআর ব্যবহার করবে না। এটি ম্যাক ওএস এর পুরানো সংস্করণগুলির জন্য কাজ করবে, যদিও আমি ওএস 9 সম্পর্কে জানি না।
মিলিওয়েজ

হাই, উত্তর দিতে খুব বেশি দেরি হয়নি। এই উত্তরটি পড়ার পরে আমি রুবি শার্লোট মণি প্রসারিত করেছি। এটি এখন উপরের ফর্ম্যাটগুলি বেশ ভালভাবে সনাক্ত করছে। Stackoverflow.com/a/64276978/2731103
টম ফ্রয়েডেনবার্গ

10

মজিলা nsUniversalDtetector (পার্ল বাইন্ডিংস: এনকোড :: ডিটেক্ট / এনকোড :: ডিটেক্ট :: ডিটেক্টর ) মিলিয়নগুণ প্রমাণিত।


আরও ডকুমেন্টেশন এখানে পাওয়া যায়: mozilla.org/projects/intl/detectorsrc.html , সেখান থেকে, এটি প্রস্তাব দেয় যে আপনি যদি ডক্সে খনন করেন তবে আপনি সমর্থিত অক্ষরগুলি খুঁজে পেতে পারেন
জোয়েল বার্গার

@ জোয়েল: আমি উত্সটি খনন করেছি। এটা ছিল একটি বাজে প্রশ্ন। x-mac-cyrillicসমর্থিত, x-mac-hebrewমন্তব্যে দীর্ঘ আলোচনা করা হয়, x-mac-anything-elseউল্লেখ পাওয়া যায় না।
জন মাচিন

@ জন মাচিন: এই সিরিয়ালিক এবং হিব্রুউ একটি সম্মতি পেয়েছে, তবে অন্য কিছুই নয় d আমি কেবলমাত্র অন্য একটি ডকুমেন্টেশন উত্সে টস করছিলাম, আমি আর পড়িনি, এটি করার জন্য ধন্যবাদ!
জোয়েল বার্গার

7

এ জাতীয় তাত্পর্যপূর্ণ বিষয়ে আমার প্রচেষ্টা (ধরে নিই যে আপনি ASCII এবং UTF-8 এড়িয়ে গেছেন):

  • যদি 0x7f থেকে 0x9f একেবারে উপস্থিত না হয়, এটি সম্ভবত আইএসও -8859-1, কারণ এগুলি খুব কমই নিয়ন্ত্রণ কোড ব্যবহৃত হয়।
  • 0x91 থেকে 0x94 এর মধ্যে যদি খুব উপস্থিত হয় তবে সম্ভবত এটি উইন্ডোজ -1222 কারণ এটি "স্মার্ট উক্তি", ইংরাজী পাঠ্যে ব্যবহারের জন্য এই শ্রেণির সম্ভবত সবচেয়ে বেশি অক্ষর। আরও নিশ্চিত হওয়ার জন্য, আপনি জোড়গুলি সন্ধান করতে পারেন।
  • অন্যথায় এটি ম্যাক্রোম্যান, বিশেষত যদি আপনি 0xd5 এর মাধ্যমে 0xd2 এর প্রচুর পরিমাণ দেখতে পান (তবে সেখানে টাইপোগ্রাফিক উদ্ধৃতি ম্যাকরোম্যানে রয়েছে)।

সাইড নোট:

জাভা উত্সের মতো ফাইলগুলির জন্য যেখানে ফাইলের অভ্যন্তরে এ জাতীয় কোনও সুবিধা নেই, আপনি এক্সটেনশনের আগে এনকোডিংটি রাখবেন, যেমন সামারক্লাস-utf8.java

এটা করো না!!

জাভা সংকলকটি ক্লাসের নামের সাথে মেলে ফাইলের নাম প্রত্যাশা করে, সুতরাং ফাইলগুলির নাম পরিবর্তন করে উত্স কোডটি বিবিধ করে তুলবে। সঠিক জিনিস এনকোডিং অনুমান, তারপর ব্যবহার হবে native2asciiসরঞ্জামে সমস্ত অ-ASCII অক্ষর রূপান্তর করতে ইউনিকোড পালাবার ক্রম


7
স্টোপিড কমপিলার! না, আমরা লোকদের বলতে পারি না তারা কেবল এএসসিআইআই ব্যবহার করতে পারে; এটি আর 1960 এর দশক নয়। যদি কোনও @ এনকোডিং টীকা থাকে তবে সমস্যাটি হবে না যাতে উত্সটি কোনও নির্দিষ্ট এনকোডিংয়ে থাকা সত্যটি উত্স কোডের বাইরে বহিরাগত রাখতে বাধ্য হয় না, জাভার সত্যিকারের বোকা ঘাটতি যা পার্ল বা পাইথনকেই ভোগে না । এটি উত্স হতে হবে। যদিও এটি আমাদের মূল সমস্যা নয়; এটি *.textফাইলের সংখ্যা।
tchrist

4
@ ক্রিশ্চট: এ জাতীয় টীকাকে সমর্থন করার জন্য আপনার নিজের এন্টোটেশন প্রসেসরটি লিখতে আসলে এত কঠিন কাজ হবে না। স্ট্যান্ডার্ড এপিআইতে এটি না রাখার জন্য এখনও একটি বিব্রতকর নজরদারি।
মাইকেল বর্গওয়ার্ট

এমনকি জাভা @ এনকোডিং সমর্থন করলেও, এটি এনকোডিংয়ের ঘোষণা সঠিক হওয়া নিশ্চিত করবে না ।
dan04

4
@ ডান04: আপনি এক্সএমএল, এইচটিএমএল বা অন্য কোথাও এনকোডিং ঘোষণার বিষয়ে একই কথা বলতে পারেন। তবে ঠিক সেই উদাহরণগুলির মতোই, যদি এটি স্ট্যান্ডার্ড এপিআইতে সংজ্ঞায়িত করা হয় তবে বেশিরভাগ সরঞ্জাম যা সোর্স কোড (বিশেষত সম্পাদক এবং আইডিই) দিয়ে কাজ করে এটি সমর্থন করবে, যা লোককে দুর্ঘটনাক্রমে এমন ফাইল তৈরি করা থেকে বিরত রাখতে পারে যার বিষয়বস্তুগুলির এনকোডিং মেলে না would ঘোষণা।
মাইকেল বর্গওয়ার্ট

4
"জাভা সংকলক ফাইলের নাম শ্রেণীর নামের সাথে মেলে বলে প্রত্যাশা করে।" এই নিয়মটি কেবল তখনই প্রয়োগ হয় যদি ফাইলটি একটি উচ্চ-স্তরের পাবলিক শ্রেণির সংজ্ঞা দেয়।
ম্যাথু ফ্ল্যাশেন

6

"পার্ল, সি, জাভা বা পাইথন এবং সেই ক্রমে": আকর্ষণীয় মনোভাব :-)

"কিছু সম্ভবত ইউটিএফ -8 হয় কিনা তা আমরা জানার একটি ভাল পরিবর্তন": আসলে ইউটিএফ -8 অদৃশ্যভাবে ছোট হওয়ায় উচ্চ-বিট-সেট বাইটস ব্যবহার করে এমন কিছু অন্যান্য চরসেটে অর্থবহ পাঠ্য এনকোডযুক্ত একটি ফাইল সফলভাবে ডিকোড হওয়ার সম্ভাবনা রয়েছে।

ইউটিএফ -8 কৌশলগুলি (কমপক্ষে পছন্দের ভাষায়):

# 100% Unicode-standard-compliant UTF-8
def utf8_strict(text):
    try:
        text.decode('utf8')
        return True
    except UnicodeDecodeError:
        return False

# looking for almost all UTF-8 with some junk
def utf8_replace(text):
    utext = text.decode('utf8', 'replace')
    dodgy_count = utext.count(u'\uFFFD') 
    return dodgy_count, utext
    # further action depends on how large dodgy_count / float(len(utext)) is

# checking for UTF-8 structure but non-compliant
# e.g. encoded surrogates, not minimal length, more than 4 bytes:
# Can be done with a regex, if you need it

একবার আপনি সিদ্ধান্ত নিয়েছেন যে এটি না এএসসিআইআই বা ইউটিএফ -8:

মজিলা-বংশোদ্ভূত চরসেট সনাক্তকারী যে আমি ম্যাকরোম্যানকে সমর্থন করি না এবং যে কোনও ক্ষেত্রে 8-বিট চরসেটগুলিতে বিশেষত ইংরাজির সাথে ভাল কাজ করবেন না কারণ এএএএএফআইসিটি তারা প্রদত্ত ডিকোডিংটি বোঝায় কিনা তা খতিয়ে দেখার উপর নির্ভর করে ভাষা, বিরামচিহ্ন অক্ষর উপেক্ষা করা এবং সেই ভাষায় নথির বিস্তৃত নির্বাচনের উপর ভিত্তি করে

অন্যরা যেমন মন্তব্য করেছেন, আপনার কাছে কেবলমাত্র সিপি 1252 এবং ম্যাক্রোম্যানের মধ্যে পার্থক্য করার জন্য উচ্চ-বিট-সেট বিরামচিহ্নগুলি পাওয়া যায়। আমি শেক্সপিয়ার বা হ্যান্সার্ড বা কেজেভি বাইবেল নয়, নিজের নথিতে মোজিলা ধরণের মডেলটি প্রশিক্ষণের পরামর্শ দিচ্ছি এবং সমস্ত 256 বাইট বিবেচনায় নিয়েছি। আমি অনুমান করি যে আপনার ফাইলগুলিতে কোনও মার্কআপ নেই (এইচটিএমএল, এক্সএমএল, ইত্যাদি) - যা সম্ভবত কিছুটা হতভম্ব করে দেবে ort

আপনি এমন ফাইলগুলি উল্লেখ করেছেন যা বেশিরভাগ ইউটিএফ -8 কিন্তু ডিকোড করতে ব্যর্থ হয়। আপনার এ সম্পর্কে খুব সন্দেহজনক হওয়া উচিত:

(1) ফাইলগুলি যা আইএসও -8859-1 এ এনকোড করা হয়েছে তবে 0x80 থেকে 0x9F অন্তর্ভুক্তে "নিয়ন্ত্রণ অক্ষর" ধারণ করে ... এটি এতটাই প্রচলিত যে খসড়া এইচটিএমএল 5 স্ট্যান্ডার্ডটি আইএসও -8859 হিসাবে ঘোষিত সমস্ত এইচটিএমএল স্ট্রিমগুলি ডিকোড করতে বলেছে -1 সিপি 1252 ব্যবহার করে।

(২) ফাইলগুলি যেগুলি ইউটিএফ -8 হিসাবে ঠিক আছে ডিকোড করে তবে ফলস্বরূপ ইউনিকোডে U + 0080 থেকে U + 009F সমেত অন্তর্ভুক্ত "নিয়ন্ত্রণের অক্ষর" থাকে ... এটি সিপি 1252 / সিপি 850 (এটি ঘটতে দেখেছি!) ট্রান্সকোডিং হতে পারে can "আইএসও -8859-1" থেকে ইউটিএফ -8 এ ফাইলগুলি।

পটভূমি: পাইথন-ভিত্তিক চরসেট আবিষ্কারক তৈরি করার জন্য আমার কাছে একটি ভিজে-রবিবার-বিকেলে একটি প্রকল্প রয়েছে যা ফাইল-ভিত্তিক (ওয়েব-ওরিয়েন্টেডের পরিবর্তে) এবং legacy ** nসিপি 850 এবং সিপি 437 এর মতো 8-বিট অক্ষর সেটগুলির সাথে ভাল কাজ করে । এটি এখনও প্রাইম টাইমের কাছাকাছি নেই। আমি ফাইল প্রশিক্ষণে আগ্রহী; আপনার আইএসও -8859-1 / সিপি 1252 / ম্যাক্রোম্যান ফাইলগুলি কি সমানভাবে "অবিচ্ছিন্ন" হিসাবে রয়েছে আপনি যে কারও কোড সমাধান হিসাবে প্রত্যাশা করছেন?


4
ভাষা অর্ডার করার কারণ পরিবেশ। আমাদের বেশিরভাগ বড় অ্যাপ্লিকেশনগুলি জাভা এবং ছোটখাটো উপযোগিতা এবং কিছু অ্যাপ্লিকেশনগুলি ঝুঁকির মধ্যে রয়েছে। আমাদের এখানে কিছুটা কোড রয়েছে এবং অজগরটি রয়েছে। আমি বেশিরভাগ সি এবং পার্ল প্রোগ্রামার, কমপক্ষে প্রথম পছন্দ অনুসারে, তাই আমি আমাদের অ্যাপ্লিকেশন লাইব্রেরিতে প্লাগ করতে কোনও জাভা সমাধান, বা তার জন্য পার্ল লাইব্রেরি খুঁজছিলাম। যদি সি, আমি পার্স ইন্টারফেসের সাথে এটি সংযোগ স্থাপনের জন্য একটি এক্সএস আঠালো স্তর তৈরি করতে পারতাম, তবে পাইথনের আগে আমি এটি আগে কখনও করিনি।
tchrist

3

যেমনটি আপনি আবিষ্কার করেছেন, এই সমস্যাটি সমাধান করার কোনও সঠিক উপায় নেই, কারণ কোন ফাইলকে এনকোডিং করা হয় সে সম্পর্কে নিখুঁত জ্ঞান ছাড়া, সমস্ত 8-বিট এনকোডিং হুবহু: বাইটের সংগ্রহ A সমস্ত বাইট সমস্ত 8-বিট এনকোডিংয়ের জন্য বৈধ।

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

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


1

আপনি যদি ম্যাক্রোম্যানের জন্য প্রতিটি এনকোডিং এক্সেসপটি সনাক্ত করতে পারেন, তবে এটিরূপে ধারণা করা যৌক্তিক হবে যেগুলি যেগুলি ডিক্রিফাই করা যায় না তা ম্যাক্রোম্যানে রয়েছে। অন্য কথায়, কেবলমাত্র এমন ফাইলগুলির একটি তালিকা তৈরি করুন যা প্রক্রিয়া করা যায় নি এবং সেগুলি হ্যান্ডেল করে যেন তারা ম্যাক্রোম্যান।

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

শেষ অবধি, কেবলমাত্র বিদ্যমান সমস্ত ফাইলকে একক ফর্ম্যাটে রূপান্তর করা ভাল নয় এবং সেই নতুন ফর্ম্যাটে থাকা নতুন ফাইলগুলির প্রয়োজন।


5
হাস্যকর! ৩০ মিনিটের জন্য বাধা দেওয়ার পরে আমি যখন প্রথম এই মন্তব্যটি পড়েছিলাম, তখন আমি "ম্যাক্রোম্যান" "ম্যাক্রো ম্যান" হিসাবে পড়েছিলাম এবং ম্যাক্রোম্যানের সাথে সংযোগ স্থাপন করি না যতক্ষণ না আমি এই স্ট্রিংটির জন্য অনুসন্ধান চালিয়ে যাব যে ওপি উল্লেখ করেছে কিনা তা দেখার জন্য
অ্যাড্রিয়ান প্রোঙ্ক

এই উত্তরটি +1 এক ধরণের আকর্ষণীয়। এটি ভাল বা খারাপ ধারণা কিনা তা নিশ্চিত নন। যে কেউ এমন একটি বিদ্যমান এনকোডিংয়ের কথা চিন্তা করতে পারে যা সনাক্তও করা যায় না? ভবিষ্যতে এক হওয়ার সম্ভাবনা আছে কি?
ব্যবহারকারীর নাম

1

জিলিয়ন লিগ্যাসি টেক্সট ফাইলগুলির এলোমেলোভাবে এনকোড করে অন্য কারও কি এই সমস্যা আছে? যদি তা হয় তবে আপনি কীভাবে এটি সমাধান করার চেষ্টা করেছিলেন এবং আপনি কতটা সফল?

আমি বর্তমানে একটি প্রোগ্রাম লিখছি যা এক্সএমএলে ফাইলগুলি অনুবাদ করে। এটি প্রতিটি ফাইলের ধরণটি স্বয়ংক্রিয়ভাবে আবিষ্কার করতে হবে, যা একটি পাঠ্য ফাইলের এনকোডিং নির্ধারণের সমস্যার সুপারস্টেট। এনকোডিং নির্ধারণের জন্য আমি একটি বয়েসিয়ান পদ্ধতির ব্যবহার করছি। এটি হ'ল, আমার শ্রেণিবদ্ধকরণ কোডটি একটি সম্ভাবনা (সম্ভাবনা) গণনা করে যে কোনও পাঠ্য ফাইলে এটি বোঝে এমন সমস্ত এনকোডিংয়ের জন্য একটি নির্দিষ্ট এনকোডিং রয়েছে। প্রোগ্রামটি তখন সবচেয়ে সম্ভাব্য ডিকোডার নির্বাচন করে। বায়েশিয়ান পদ্ধতির প্রতিটি এনকোডিংয়ের জন্য এটি কাজ করে।

  1. প্রাথমিক ( পূর্বের ) সম্ভাবনাটি সেট করুন যে ফাইলটি প্রতিটি এনকোডিংয়ের ফ্রিকোয়েন্সিগুলির উপর ভিত্তি করে এনকোডিংয়ে রয়েছে।
  2. ফাইলে প্রতিটি বাইট পরীক্ষা করে দেখুন। সেই বাইট মান উপস্থিত থাকা এবং একটি এনকোডিংয়ে থাকা কোনও ফাইলের মধ্যে পারস্পরিক সম্পর্ক নির্ধারণ করতে বাইট মানটি সন্ধান করুন। ফাইলটি এনকোডিংয়ে রয়েছে এমন একটি নতুন ( উত্তরোত্তর ) সম্ভাবনা গণনা করতে সেই সম্পর্কটি ব্যবহার করুন । যদি আপনার আরও বাইট পরীক্ষা করতে হয়, আপনি পরবর্তী বাইট পরীক্ষা করার সময় সেই বাইটের পরবর্তী সম্ভাব্যতা পূর্বের সম্ভাবনা হিসাবে ব্যবহার করুন।
  3. আপনি যখন ফাইলটির শেষে পৌঁছে যান (আমি আসলে প্রথম 1024 বাইট দেখেছি) তখন আপনার সম্ভাবনাটি ফাইলটি এনকোডিংয়ে থাকার সম্ভাবনা।

এটি পরিবাহিত করে যে বেয়েসের উপপাদ্যটি করা খুব সহজ হয়ে ওঠে যদি সম্ভাবনাগুলি গণনার পরিবর্তে আপনি গণনা করেন তথ্য বিষয়বস্তু রয়েছে, এর মধ্যে লগারিদম হয় মতভেদ : info = log(p / (1.0 - p))

আপনি ম্যানুয়ালি শ্রেণিবদ্ধ করেছেন এমন একটি ফাইলের কর্পাস পরীক্ষা করে আপনাকে আরম্ভের পূর্বের সম্ভাবনা এবং পারস্পরিক সম্পর্কগুলি গণনা করতে হবে।


1

গৃহীত উত্তরের সাহায্যে নেতৃত্ব দেওয়া https://stackoverflow.com/a/4200765/2731103 আমি অনুরোধ করা এনকোডিংগুলি বেশিরভাগই সঠিক হিসাবে চিহ্নিত করতে রুবি রত্ন "শার্লোট" উন্নত করতে পারি।

আমদানির আগে সিএসভি ফাইল এনকোডিংগুলি সনাক্ত করার জন্য আমরা উত্পাদনশীল পরিবেশে এটি ব্যবহার করি

এটি যুক্তিসঙ্গত অংশ (রুবি)

UTF8HASBOM = /^\xEF\xBB\xBF/n      #  [239, 187, 191]
UTF32LEBOM = /^\xFF\xFE\x00\x00/n  # [255, 254, 0, 0]
UTF32BEBOM = /^\x00\x00\xFE\xFF/n  # [0, 0, 254, 255]

UTF16LEBOM = /^\xFF\xFE/n                # [255, 254]
UTF16BEBOM = /^\xFE\xFF/n                # [254, 255]

NOTIN1BYTE = /[\x00-\x06\x0B\x0E-\x1A\x1C-\x1F\x7F]/n
NOTISO8859 = /[\x00-\x06\x0B\x0E-\x1A\x1C-\x1F\x7F\x80-\x84\x86-\x9F]/n

# Information to identify MacRoman
# /programming/4198804/
NOTINCP1252 = /[\x81\x8D\x8F\x90\x9D]/n
CP1252CHARS = /[\x92\x95\x96\x97\xAE\xB0\xB7\xE8\xE9\xF6]/n
MCROMNCHARS = /[\x8E\x8F\x9A\xA1\xA5\xA8\xD0\xD1\xD5\xE1]/n
detect.force_encoding('BINARY') # Needed to prevent non-matching regex charset.
sample = detect[0..19]     # Keep sample string under 23 bytes.
detect.sub!(UTF8HASBOM, '') if sample[UTF8HASBOM] # Strip any UTF-8 BOM.

# See: http://www.daniellesucher.com/2013/07/23/ruby-case-versus-if/
if    sample.ascii_only? && detect.force_encoding('UTF-8').valid_encoding?

elsif sample[UTF32LEBOM] && detect.force_encoding('UTF-32LE').valid_encoding?
elsif sample[UTF32BEBOM] && detect.force_encoding('UTF-32BE').valid_encoding?
elsif sample[UTF16LEBOM] && detect.force_encoding('UTF-16LE').valid_encoding?
elsif sample[UTF16BEBOM] && detect.force_encoding('UTF-16BE').valid_encoding?

elsif detect.force_encoding('UTF-8').valid_encoding?

elsif detect.force_encoding('BINARY')[NOTISO8859].nil?
  detect.force_encoding('ISO-8859-1')

elsif detect.force_encoding('BINARY')[NOTIN1BYTE].nil?

  if  detect.force_encoding('BINARY')[NOTINCP1252].nil? &&
            detect.force_encoding('BINARY').scan(MCROMNCHARS).length < detect.force_encoding('BINARY').scan(CP1252CHARS).length

      detect.force_encoding('Windows-1252')
  else
      detect.force_encoding('MacRoman')
  end

else  detect.force_encoding('BINARY')
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.