{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encode_table=[0, 15, 19, 28, 37, 42, 54, 57, 70, 73, 85, 90, 99, 108, 112, 127]\n",
    "decode_table=[0, 0, 0, 2, 0, 4, 8, 1, 0, 9, 5, 1, 3, 1, 1, 1, 0, 2, 2, 2, 3, 10, 6, 2, 3, 7, 11, 2, 3, 3, 3, 1, 0, 4, 5, 12, 4, 4, 6, 4, 5, 7, 5, 5, 13, 4, 5, 1, 14, 7, 6, 2, 6, 4, 6, 6, 7, 7, 5, 7, 3, 7, 6, 15, 0, 9, 8, 12, 8, 10, 8, 8, 9, 9, 11, 9, 13, 9, 8, 1, 14, 10, 11, 2, 10, 10, 8, 10, 11, 9, 11, 11, 3, 10, 11, 15, 14, 12, 12, 12, 13, 4, 8, 12, 13, 9, 5, 12, 13, 13, 13, 15, 14, 14, 14, 12, 14, 10, 6, 15, 14, 7, 11, 15, 13, 15, 15, 15]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "import socket\n",
    "\n",
    "HOST = '192.168.137.20'\n",
    "PORT = 5000\n",
    "server_addr = (HOST, PORT)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Encode with table"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def hamming_encode_table_method(plaintext):\n",
    "    return_list=list()\n",
    "    for s in range(len(plaintext)):\n",
    "        ### for debug check \n",
    "        # print(s) \n",
    "        # codeword1 = encode_table[int(plaintext[s]/16)]\n",
    "        # print(codeword1)\n",
    "        return_list.append(encode_table[int(plaintext[s]/16)])\n",
    "        # codeword2 = encode_table[int(plaintext[s]%16)]\n",
    "        # print(codeword2)\n",
    "        return_list.append(encode_table[int(plaintext[s]%16)])\n",
    "        # print(return_bytes)\n",
    "    return bytes(return_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Decode with table"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def hamming_decode_table_method(encryptext):\n",
    "    return_list=list()\n",
    "    for s in range(len(encryptext)):\n",
    "        if s % 2 ==0:\n",
    "            high_nibble=decode_table[int(encryptext[s])]\n",
    "            low_nibble=decode_table[int(encryptext[s+1])]\n",
    "            c_append=high_nibble*16+low_nibble\n",
    "            # print(high_nibble)\n",
    "            # print(low_nibble)\n",
    "            # print(c_append)\n",
    "            return_list.append(c_append)\n",
    "        \n",
    "    return bytes(return_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "random add 1 bit error "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "def add_1bit_error(input_message):\n",
    "    for s in range(len(input_message)):\n",
    "        input_message[s] = (int(input_message[s]) ^ (1<< random.randint(0, 6)))\n",
    "    return input_message"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "trans_count=0\n",
    "client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)\n",
    "client_socket.settimeout(5)\n",
    "message = b'https://maker.wiznet.io/momososo'\n",
    "while True:\n",
    "    hamming_encoded_data = hamming_encode_table_method(message)\n",
    "\n",
    "    # random add 1 bit error \n",
    "    hamming_encoded_data = add_1bit_error(bytearray(hamming_encoded_data))\n",
    "\n",
    "    client_socket.sendto(bytes(hamming_encoded_data), server_addr)\n",
    "    print(f'Send:{hamming_encoded_data}')\n",
    "    try:\n",
    "        data, server = client_socket.recvfrom(2048)\n",
    "        hamming_decoded_data = hamming_decode_table_method(data)\n",
    "        \n",
    "        print(f'Decode:{hamming_decoded_data}')\n",
    "        if hamming_decoded_data != message:\n",
    "            print('Recive error')\n",
    "            print(f'already trans:{trans_count}')\n",
    "            break\n",
    "        else:\n",
    "            trans_count+=1\n",
    "\n",
    "        # print(len(hamming_decoded_data))\n",
    "        # message += hamming_decoded_data # lenth test stop at 2048 bytes\n",
    "\n",
    "    except socket.timeout:\n",
    "        print('REQUEST TIMED OUT')\n",
    "        break\n",
    "client_socket.close()\n",
    "    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ryzen-ai-1.2.0",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
