পাঠ ১০ · ৫৭-এর মধ্যে · মডিউল ৩
Home / Courses / Computer Networks / এরর কারেকশন

এরর কারেকশন — Hamming কোড পরিচিতি

Error correction — introduction to Hamming code
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • এরর ডিটেকশন ও এরর কারেকশনের মধ্যে মৌলিক পার্থক্য, এবং কখন কারেকশন বেশি প্রয়োজনীয়
  • Hamming কোডের মূল ধারণা — প্যারিটি বিট পজিশনিং ও কভারেজ
  • সিনড্রোম কীভাবে সরাসরি এরর পজিশন নির্দেশ করে
  • Python-এ একটি বাস্তব Hamming(7,4) hamming_encode/hamming_decode ইমপ্লিমেন্টেশন — যা রানটাইমে নিজেই একটি বিট-ফ্লিপ ঠিক করে দেখায়

১ · এরর ডিটেকশনের বাইরে — কেন কারেকশন দরকার

L09-এর CRC আমাদের বলে দেয় একটি ফ্রেম করাপ্ট হয়েছে কিনা — কিন্তু ঠিক কোন বিট ভুল, তা বলে না। সমাধান সাধারণত হয় পুনরায় পাঠানোর অনুরোধ করা (retransmission)। কিন্তু কিছু পরিস্থিতিতে পুনরায় পাঠানো ব্যয়বহুল বা অসম্ভব — যেমন ডিপ-স্পেস যোগাযোগ (একটি স্যাটেলাইট থেকে পৃথিবীতে সিগন্যাল পৌঁছাতে মিনিট লাগতে পারে, পুনরায় অনুরোধ করা অব্যবহারিক) বা RAM এরর কারেকশন (মেমরিতে সিঙ্গেল-বিট এরর প্রতি মুহূর্তে ঘটতে পারে, প্রতিবারই "পুনরায় পড়ুন" বলা অচল)। এই পরিস্থিতিতে দরকার এমন একটি কোড যা এরর নিজে থেকেই ঠিক করে ফেলতে পারে — এটিই Hamming কোডHamming Codeএকটি এরর-কারেকটিং কোড যা প্যারিটি বিটকে নির্দিষ্ট পজিশনে বসিয়ে সিঙ্গেল-বিট এরর নিজে থেকেই সনাক্ত ও সংশোধন করতে পারে, পুনরায় পাঠানো ছাড়াই।-এর কাজ।

২ · মূল ধারণা — প্যারিটি বিট পজিশনিং ও কভারেজ

Hamming(7,4)-এ ৪টি ডেটা বিটের সাথে ৩টি প্যারিটি বিট যোগ করে মোট ৭ বিটের একটি কোডওয়ার্ড তৈরি হয়। প্যারিটি বিটগুলো বসে ২-এর ঘাত পজিশনে — ১, ২, ৪ — আর ডেটা বিটগুলো বসে বাকি পজিশনে — ৩, ৫, ৬, ৭।

প্যারিটি বিট P1 (পজিশন ১)
কভার করে সেইসব পজিশন যাদের বাইনারি রিপ্রেজেন্টেশনে সর্বনিম্ন (১-নম্বর) বিট সেট আছে — অর্থাৎ ৩, ৫, ৭।
প্যারিটি বিট P2 (পজিশন ২)
কভার করে সেইসব পজিশন যাদের বাইনারিতে ২-নম্বর বিট সেট — অর্থাৎ ৩, ৬, ৭।
প্যারিটি বিট P4 (পজিশন ৪)
কভার করে সেইসব পজিশন যাদের বাইনারিতে ৪-নম্বর বিট সেট — অর্থাৎ ৫, ৬, ৭।

প্রতিটি প্যারিটি বিট তার কভার করা পজিশনগুলোর মধ্যে (নিজেসহ) জোড় প্যারিটি বজায় রাখে। এই ওভারল্যাপিং কভারেজই মূল কৌশল — প্রতিটি ডেটা পজিশন একাধিক প্যারিটি বিটের কভারেজে পড়ে একটি অনন্য সংমিশ্রণে, যা পরে ঠিক কোন বিট ভুল তা শনাক্ত করতে ব্যবহৃত হয়।

৩ · সিনড্রোম — কীভাবে এরর পজিশন সরাসরি বের হয়

রিসিভার প্রাপ্ত ৭ বিট থেকে প্রতিটি প্যারিটি চেক (P1, P2, P4) পুনরায় হিসাব করে। কোনো চেক যদি ব্যর্থ হয় (প্যারিটি ভুল), সেই প্যারিটি বিটের পজিশন মান (১, ২, বা ৪) একটি সমষ্টিতে (সিনড্রোম) যোগ হয়। যেমন — শুধু P1 আর P4 ব্যর্থ হলে সিনড্রোম = ১ + ৪ = ৫, যার মানে পজিশন ৫-এর বিট ফ্লিপ হয়েছে — সেটিকে উল্টে দিলেই মূল ডেটা ফিরে আসে। সিনড্রোম শূন্য হলে কোনো এরর নেই।

Python
# Hamming(7,4) -- বাস্তব এনকোড/ডিকোড, সিনড্রোম-ভিত্তিক সিঙ্গেল-বিট এরর কারেকশন
# পজিশন ১..৭ (১-ইনডেক্সড): প্যারিটি বিট বসে ১, ২, ৪-এ; ডেটা বিট বসে ৩, ৫, ৬, ৭-এ

DATA_POS = [3, 5, 6, 7]
PARITY_POS = [1, 2, 4]

def hamming_encode(data_bits):
    """data_bits: ৪-বিটের '0'/'1' স্ট্রিং। রিটার্ন করে ৭-বিটের কোডওয়ার্ড।"""
    bits = [0] * 8  # ইনডেক্স 0 ব্যবহার হয় না, আমরা 1..7 ব্যবহার করি
    for i, pos in enumerate(DATA_POS):
        bits[pos] = int(data_bits[i])
    for p in PARITY_POS:
        parity = 0
        for pos in range(1, 8):
            if pos != p and (pos & p):   # pos-এর বাইনারিতে p-বিট সেট থাকলে কভার করে
                parity ^= bits[pos]
        bits[p] = parity
    return ''.join(str(bits[pos]) for pos in range(1, 8))

def hamming_decode(codeword):
    """codeword: ৭-বিট স্ট্রিং। রিটার্ন করে (সংশোধিত ৪-বিট ডেটা, সিনড্রোম)।"""
    bits = [0] + [int(b) for b in codeword]  # bits[1..7]
    syndrome = 0
    for p in PARITY_POS:
        parity = 0
        for pos in range(1, 8):
            if pos & p:
                parity ^= bits[pos]
        if parity != 0:
            syndrome += p
    corrected = bits[:]
    if syndrome != 0:
        corrected[syndrome] ^= 1   # সিনড্রোম-নির্দেশিত পজিশনের বিট উল্টে দেওয়া
    data = ''.join(str(corrected[pos]) for pos in DATA_POS)
    return data, syndrome

# --- এনকোড করি ---
original_data = "1011"
codeword = hamming_encode(original_data)
print("মূল ৪-বিট ডেটা:      ", original_data)
print("এনকোডেড ৭-বিট কোডওয়ার্ড:", codeword, "(কোড নিজে হিসাব করেছে)")

# --- ইচ্ছাকৃতভাবে ঠিক একটি বিট ফ্লিপ করি ---
flip_position = 5   # ১-ইনডেক্সড পজিশন
corrupted = list(codeword)
corrupted[flip_position - 1] = '1' if corrupted[flip_position - 1] == '0' else '0'
corrupted = ''.join(corrupted)
print(f"\nবিট পজিশন {flip_position} ফ্লিপ করে করাপ্ট করা হলো: {corrupted}")

# --- ডিকোড করে দেখি সিনড্রোম সঠিক পজিশন ধরতে পারে কিনা ---
recovered_data, syndrome = hamming_decode(corrupted)
print("গণনাকৃত সিনড্রোম:      ", syndrome, f"(আশানুরূপ: {flip_position})")
print("সংশোধিত ৪-বিট ডেটা:  ", recovered_data)
print("মূল ডেটার সাথে হুবহু মিলছে?", recovered_data == original_data)

assert syndrome == flip_position
assert recovered_data == original_data
print("\nসেলফ-চেক পাস: সিঙ্গেল-বিট এরর সঠিকভাবে সনাক্ত ও সংশোধিত হয়েছে।")

    
৪-বিট ডেটা এনকোড ৭-বিট কোডওয়ার্ড ১ বিট ফ্লিপ (এরর) ৩টি প্যারিটি চেক পুনরায় হিসাব সিনড্রোম = এরর পজিশন → বিট উল্টে সংশোধন
প্যারিটি চেকগুলোর ব্যর্থতার প্যাটার্ন (সিনড্রোম) সরাসরি বাইনারি সংখ্যা হিসেবে ফ্লিপ হওয়া বিটের পজিশন বলে দেয়।
লক্ষ্য করুন — উপরের কোডে flip_position-এর মান (৫) হাতে অনুমান করে বসানো হয়নি যে সিনড্রোমও ৫ হবে — বরং hamming_decode ফাংশনটি স্বাধীনভাবে প্যারিটি চেক পুনরায় হিসাব করে সিনড্রোম বের করেছে, এবং শেষে assert syndrome == flip_position দিয়ে প্রমাণ করা হয়েছে যে দুটো মিলে যায়। এটিই একটি প্রকৃত, সেলফ-ভেরিফাইং প্রদর্শন।
মূল কথা · Key takeaway

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

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ Hamming(7,4) কোড কি দুটি বিট একসাথে ফ্লিপ হলেও ঠিক করতে পারবে?

না — Hamming(7,4) শুধুমাত্র একক-বিট এরর নির্ভরযোগ্যভাবে সংশোধন করতে ডিজাইন করা হয়েছে। দুটি বিট একসাথে ফ্লিপ হলে সিনড্রোম একটি ভুল (কিন্তু অন্য কোনো বৈধ) পজিশনে নির্দেশ করতে পারে, ফলে ডিকোডার ভুল বিট সংশোধন করে ফেলতে পারে — এমনকি এরর সম্পূর্ণ অলক্ষিতও থেকে যেতে পারে। ডাবল-বিট এরর নির্ভরযোগ্যভাবে ধরতে (সংশোধন ছাড়াই) একটি অতিরিক্ত সামগ্রিক প্যারিটি বিট যোগ করে Hamming(8,4) ("SECDED" — Single Error Correction, Double Error Detection) ব্যবহার করা হয়, যা বাস্তব ECC RAM-এ প্রচলিত।

প্র ০২ কেন প্যারিটি বিটগুলো ঠিক ১, ২, ৪ পজিশনে (২-এর ঘাত) বসানো হয় — অন্য কোনো পজিশনে নয় কেন?

কারণ ২-এর ঘাত পজিশনগুলোর বাইনারি রিপ্রেজেন্টেশনে ঠিক একটি বিট সেট থাকে (১ = 001, ২ = 010, ৪ = 100) — এই বৈশিষ্ট্যই নিশ্চিত করে প্রতিটি প্যারিটি বিট একটি "স্বতন্ত্র বিট-পজিশন" যাচাই করছে, এবং একসাথে সব প্যারিটি চেকের ফলাফল সরাসরি বাইনারিতে একত্রিত করলে (সিনড্রোম) মূল এরর-পজিশনের সম্পূর্ণ বাইনারি রিপ্রেজেন্টেশন পুনর্গঠিত হয়ে যায় — এটিই পুরো স্কিমের গাণিতিক কৌশল।

প্র ০৩ Hamming কোড ও L09-এর CRC — এই দুটির মধ্যে ওভারহেড (অতিরিক্ত বিট)-এর তুলনা কেমন, এবং কেন এই ট্রেড-অফ গুরুত্বপূর্ণ?

Hamming(7,4)-এ ৪ বিট ডেটার জন্য ৩ বিট প্যারিটি লাগে (৭৫% ওভারহেড), যেখানে CRC-32-এর মতো CRC কোড কিলোবাইট-সাইজ ডেটার জন্য মাত্র ৩২ বিট চেক যোগ করে (ওভারহেড প্রায় নগণ্য) — কিন্তু CRC শুধু এরর ধরতে পারে, ঠিক করতে পারে না (পুনরায় পাঠানো লাগে)। তাই বাস্তবে বেছে নেওয়া হয় ব্যবহারের প্রেক্ষাপট অনুযায়ী — যেখানে পুনরায় পাঠানো সহজ (যেমন সাধারণ ইন্টারনেট ট্রাফিক), সেখানে কম-ওভারহেডের CRC যথেষ্ট; যেখানে পুনরায় পাঠানো ব্যয়বহুল/অসম্ভব (RAM, ডিপ-স্পেস), সেখানে বেশি-ওভারহেডের কিন্তু সেলফ-কারেক্টিং Hamming-জাতীয় কোড প্রয়োজনীয়।

অনুশীলন

  1. পরীক্ষা করুন: উপরের কোড সেলে flip_position-এর মান ১ থেকে ৭ পর্যন্ত পালাক্রমে বদলে দেখুন — প্রতিবারই syndrome সঠিক পজিশন দেখায় ও recovered_data মূল ডেটার সাথে মেলে কিনা।

    হ্যাঁ — ১ থেকে ৭ পর্যন্ত যেকোনো পজিশনের একক বিট ফ্লিপ করলেই hamming_decode-এর সিনড্রোম গণনা ঠিক সেই পজিশনটিই বের করে আনবে এবং সংশোধিত ডেটা সবসময় মূল original_data-এর সাথে হুবহু মিলবে — এটিই Hamming(7,4)-এর মূল গ্যারান্টি (একক-বিট এরর কারেকশন), যা DATA_POS/PARITY_POS-এর নির্দিষ্ট বিন্যাসের কারণে গাণিতিকভাবে নিশ্চিত।

  2. চিন্তা করুন: original_data-এর মান বদলে অন্য যেকোনো ৪-বিট মান (যেমন "0000" বা "1111") বসিয়ে দেখুন — এনকোডিং/ডিকোডিং তারপরও সঠিকভাবে কাজ করে কিনা।

    হ্যাঁ, যেকোনো ৪-বিট মানের জন্যই কাজ করবে (মোট ১৬টি সম্ভাব্য মান আছে) — কারণ hamming_encode/hamming_decode-এর যুক্তি নির্দিষ্ট ইনপুট মানের উপর নির্ভরশীল নয়, বরং পজিশন-ভিত্তিক প্যারিটি গণনার সাধারণ নিয়মের উপর নির্ভর করে — এটিই দেখায় এই ইমপ্লিমেন্টেশনটি একটি নির্দিষ্ট উদাহরণের জন্য হার্ডকোড করা নয়, বরং একটি প্রকৃত, সাধারণীকৃত অ্যালগরিদম।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
এরর ডিটেকশন — প্যারিটি, চেকসাম, CRC