[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2024-11-20 17:47:23 +00:00
parent 730ba18e89
commit ffbe3bbd86
5 changed files with 391 additions and 344 deletions

View File

@ -164,61 +164,62 @@
], ],
"source": [ "source": [
"class Graph:\n", "class Graph:\n",
" def __init__(self,adj_list:dict ={}, name=\"Graph\", directed=False):\n", " def __init__(self, adj_list: dict = {}, name=\"Graph\", directed=False):\n",
" \n",
" self.plt = plt\n", " self.plt = plt\n",
" \n", "\n",
" self.nx = nx\n", " self.nx = nx\n",
" #validation\n", " # validation\n",
" \n", "\n",
" tmp = []\n", " tmp = []\n",
" for i in adj_list:\n", " for i in adj_list:\n",
" tmp.extend(adj_list[i])\n", " tmp.extend(adj_list[i])\n",
"\n", "\n",
" \n", " if not directed and set(tmp) == set(adj_list.keys()):\n",
" if(not directed and set(tmp)==set(adj_list.keys())):\n",
" self.adj_list = adj_list\n", " self.adj_list = adj_list\n",
" self.directed = directed\n", " self.directed = directed\n",
" self.name = name\n", " self.name = name\n",
" else:\n", " else:\n",
" print(\"Error : It is not a valid graph\")\n", " print(\"Error : It is not a valid graph\")\n",
" \n", "\n",
" def __str__(self):\n", " def __str__(self):\n",
" string = \" \"+self.name+\"\\n\" \n", " string = \" \" + self.name + \"\\n\"\n",
" for i in self.adj_list.keys():\n", " for i in self.adj_list.keys():\n",
" string +=str(i)+\" : [\"+\",\".join([str(j) for j in self.adj_list[i]])+\"]\\n\"\n", " string += (\n",
" str(i) + \" : [\" + \",\".join([str(j) for j in self.adj_list[i]]) + \"]\\n\"\n",
" )\n",
" return string\n", " return string\n",
" \n", "\n",
" \n", " def add_node(self, node):\n",
" def add_node(self,node):\n",
" if node not in self.adj_list.keys():\n", " if node not in self.adj_list.keys():\n",
" self.adj_list[node]=[]\n", " self.adj_list[node] = []\n",
" else:\n", " else:\n",
" print(f\"Warning : the node'{node}' already exists\")\n", " print(f\"Warning : the node'{node}' already exists\")\n",
" def add_edge(self,node1,node2):\n", "\n",
" def add_edge(self, node1, node2):\n",
" graph = self.adj_list\n", " graph = self.adj_list\n",
" if(node1 in graph and node2 in graph):\n", " if node1 in graph and node2 in graph:\n",
" graph[node1].append(node2)\n", " graph[node1].append(node2)\n",
" if(not self.directed):\n", " if not self.directed:\n",
" graph[node2].append(node1)\n", " graph[node2].append(node1)\n",
"\n",
" def get_nodeSet(self):\n", " def get_nodeSet(self):\n",
" return list(self.adj_list.keys())\n", " return list(self.adj_list.keys())\n",
"\n",
" def get_edgSet(self):\n", " def get_edgSet(self):\n",
" edgSet = []\n", " edgSet = []\n",
" for i in self.adj_list.keys():\n", " for i in self.adj_list.keys():\n",
" for j in self.adj_list[i]:\n", " for j in self.adj_list[i]:\n",
" edgSet.append(tuple([i,j]))\n", " edgSet.append(tuple([i, j]))\n",
" return edgSet\n", " return edgSet\n",
" \n", "\n",
" \n", " def dfs(self, node):\n",
" def dfs(self,node): \n", " if node in self.adj_list.keys():\n",
" if(node in self.adj_list.keys()):\n",
" traverse = []\n", " traverse = []\n",
" visited = set()\n", " visited = set()\n",
" stack = [node]\n", " stack = [node]\n",
" while(stack):\n", " while stack:\n",
" current = stack.pop()\n", " current = stack.pop()\n",
" if(current not in visited):\n", " if current not in visited:\n",
" visited.add(current)\n", " visited.add(current)\n",
" traverse.append(current)\n", " traverse.append(current)\n",
" stack.extend(self.adj_list[current])\n", " stack.extend(self.adj_list[current])\n",
@ -226,54 +227,55 @@
" return traverse\n", " return traverse\n",
" else:\n", " else:\n",
" print(f\"Error : node'{node}' does not exist in graph\")\n", " print(f\"Error : node'{node}' does not exist in graph\")\n",
" \n", "\n",
" def bfs(self,node):\n", " def bfs(self, node):\n",
" if(node in self.adj_list.keys()):\n", " if node in self.adj_list.keys():\n",
" traverse = []\n", " traverse = []\n",
" visited = set()\n", " visited = set()\n",
" queue = [node]\n", " queue = [node]\n",
" while(queue):\n", " while queue:\n",
" current = queue.pop(0)\n", " current = queue.pop(0)\n",
" if(current not in visited):\n", " if current not in visited:\n",
" visited.add(current)\n", " visited.add(current)\n",
" traverse.append(current)\n", " traverse.append(current)\n",
" queue.extend(self.adj_list[current])\n", " queue.extend(self.adj_list[current])\n",
" return traverse\n", " return traverse\n",
" \n", "\n",
" else:\n", " else:\n",
" print(f\"Error : node'{node}' does not exist in graph\")\n", " print(f\"Error : node'{node}' does not exist in graph\")\n",
"\n", "\n",
" def getPath(self, n1,n2, path=[]):\n", " def getPath(self, n1, n2, path=[]):\n",
" g= self.adj_list\n", " g = self.adj_list\n",
" path +=[n1]\n", " path += [n1]\n",
" if n2 not in g[n1]:\n", " if n2 not in g[n1]:\n",
" for i in g[n1]:\n", " for i in g[n1]:\n",
" if(i not in path):\n", " if i not in path:\n",
" path1 = self.getPath(i, n2, path.copy())\n", " path1 = self.getPath(i, n2, path.copy())\n",
" if(path1):\n", " if path1:\n",
" return path1 \n", " return path1\n",
" else:\n", " else:\n",
" return path+[n2]\n", " return path + [n2]\n",
" \n", "\n",
" def opt_path(self, path):\n", " def opt_path(self, path):\n",
" g = self.adj_list\n", " g = self.adj_list\n",
" l= len(path)\n", " l = len(path)\n",
" path1 = path.copy()\n", " path1 = path.copy()\n",
" t=2\n", " t = 2\n",
" for i in range(l):\n", " for i in range(l):\n",
" for j in range(i+2,l):\n", " for j in range(i + 2, l):\n",
" if(abs(j-i)>t):\n", " if abs(j - i) > t:\n",
" n1 = path[i]\n", " n1 = path[i]\n",
" n2 = path[j]\n", " n2 = path[j]\n",
" if(n2 in g[n1]):\n", " if n2 in g[n1]:\n",
" path1 = path[:i+1]+path[j:]\n", " path1 = path[: i + 1] + path[j:]\n",
" t = abs(j-i)\n", " t = abs(j - i)\n",
" return path1 \n", " return path1\n",
" def sortestPath(self,n1,n2):\n", "\n",
" path = self.getPath(n1,n2)\n", " def sortestPath(self, n1, n2):\n",
" spath =self.opt_path(path)\n", " path = self.getPath(n1, n2)\n",
" spath = self.opt_path(path)\n",
" return spath\n", " return spath\n",
" \n", "\n",
" def display(self):\n", " def display(self):\n",
" G = self.nx.Graph()\n", " G = self.nx.Graph()\n",
" G.add_nodes_from(self.get_nodeSet())\n", " G.add_nodes_from(self.get_nodeSet())\n",
@ -281,15 +283,16 @@
" self.nx.draw_networkx(G)\n", " self.nx.draw_networkx(G)\n",
" self.plt.title(self.name)\n", " self.plt.title(self.name)\n",
" self.plt.show()\n", " self.plt.show()\n",
"\n",
" def makeTree(self, Root=None):\n", " def makeTree(self, Root=None):\n",
" temp_ls = dict()\n", " temp_ls = dict()\n",
" if((Root == None) or (Root not in self.adj_list.keys())):\n", " if (Root == None) or (Root not in self.adj_list.keys()):\n",
" root = list(self.adj_list.keys())[0]\n", " root = list(self.adj_list.keys())[0]\n",
" else:\n", " else:\n",
" root = Root\n", " root = Root\n",
" temp_ls[root] = [root]\n", " temp_ls[root] = [root]\n",
" stack = [root]\n", " stack = [root]\n",
" \n", "\n",
" def visite(root):\n", " def visite(root):\n",
" for i in self.adj_list[root]:\n", " for i in self.adj_list[root]:\n",
" if root not in temp_ls:\n", " if root not in temp_ls:\n",
@ -298,30 +301,30 @@
" stack.append(i)\n", " stack.append(i)\n",
" temp_ls[root].append(i)\n", " temp_ls[root].append(i)\n",
" visite(i)\n", " visite(i)\n",
" \n", "\n",
" visite(root)\n", " visite(root)\n",
" \n", "\n",
" return temp_ls\n", " return temp_ls\n",
"\n", "\n",
"\n",
"adj_list = {\n", "adj_list = {\n",
" 0:[3,5,9,10,1],\n", " 0: [3, 5, 9, 10, 1],\n",
" 1:[6,7,4,0,10],\n", " 1: [6, 7, 4, 0, 10],\n",
" 2:[10,5],\n", " 2: [10, 5],\n",
" 3:[0],\n", " 3: [0],\n",
" 4:[1,5,8],\n", " 4: [1, 5, 8],\n",
" 5:[2,0,4],\n", " 5: [2, 0, 4],\n",
" 6:[1],\n", " 6: [1],\n",
" 7:[1],\n", " 7: [1],\n",
" 8:[4],\n", " 8: [4],\n",
" 9:[0],\n", " 9: [0],\n",
" 10:[2,0]\n", " 10: [2, 0],\n",
"}\n", "}\n",
"g = Graph(adj_list,name=\"Demo\")\n", "g = Graph(adj_list, name=\"Demo\")\n",
"g.display()\n", "g.display()\n",
"for i in adj_list:\n", "for i in adj_list:\n",
" \n", " g1 = Graph(g.makeTree(Root=i), name=\"Demo tree_\" + str(i))\n",
" g1 = Graph(g.makeTree(Root=i),name=\"Demo tree_\"+str(i))\n", " g1.display()"
" g1.display()\n"
] ]
}, },
{ {
@ -356,9 +359,9 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"print(g)\n", "print(g)\n",
"g.add_edge(8,10)\n", "g.add_edge(8, 10)\n",
"print(g)\n", "print(g)\n",
"print(g.sortestPath(8,10))\n", "print(g.sortestPath(8, 10))\n",
"g.display()" "g.display()"
] ]
}, },
@ -389,40 +392,44 @@
], ],
"source": [ "source": [
"class Tree:\n", "class Tree:\n",
" def __init__(self,data, parent = None):\n", " def __init__(self, data, parent=None):\n",
" self.data = data\n", " self.data = data\n",
" self.childs=[]\n", " self.childs = []\n",
" def addChild(self,*nodes):\n", "\n",
" childs=[Tree(i, parent=self) for i in nodes]\n", " def addChild(self, *nodes):\n",
" childs = [Tree(i, parent=self) for i in nodes]\n",
" self.childs.extend(childs)\n", " self.childs.extend(childs)\n",
" if (len(childs)==1):\n", " if len(childs) == 1:\n",
" return childs[0]\n", " return childs[0]\n",
" return childs\n", " return childs\n",
" \n", "\n",
" def getChilds(self):\n", " def getChilds(self):\n",
" return [i.data for i in self.childs]\n", " return [i.data for i in self.childs]\n",
"\n",
" def getElements(self):\n", " def getElements(self):\n",
" elements = [self.data]\n", " elements = [self.data]\n",
" for i in self.childs:\n", " for i in self.childs:\n",
" elements.extend(i.getElements())\n", " elements.extend(i.getElements())\n",
" return elements\n", " return elements\n",
"\n",
" def traverse(self, order=\"pre\"):\n", " def traverse(self, order=\"pre\"):\n",
" ls = []\n", " ls = []\n",
" if(order==\"pre\"):\n", " if order == \"pre\":\n",
" ls.append(self.data)\n", " ls.append(self.data)\n",
" for i in self.childs:\n", " for i in self.childs:\n",
" ls.extend(i.traverse(order=order))\n", " ls.extend(i.traverse(order=order))\n",
" return ls\n", " return ls\n",
" elif(order==\"post\"):\n", " elif order == \"post\":\n",
" for i in self.childs:\n", " for i in self.childs:\n",
" ls.extend(i.traverse(order=order))\n", " ls.extend(i.traverse(order=order))\n",
" ls.append(self.data)\n", " ls.append(self.data)\n",
" return ls\n", " return ls\n",
" \n", "\n",
"\n",
"tree = Tree(1)\n", "tree = Tree(1)\n",
"t2 = tree.addChild(2)\n", "t2 = tree.addChild(2)\n",
"t2t3 = t2.addChild(2,3,4,5,1,7,9)\n", "t2t3 = t2.addChild(2, 3, 4, 5, 1, 7, 9)\n",
"tree.addChild(90,23,41)\n", "tree.addChild(90, 23, 41)\n",
"tree.getElements()\n", "tree.getElements()\n",
"# tree.traverse()" "# tree.traverse()"
] ]
@ -464,138 +471,137 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"class BTree:\n", "class BTree:\n",
" def __init__(self,data, parent=None):\n", " def __init__(self, data, parent=None):\n",
" self.data = data\n", " self.data = data\n",
" self.left = None\n", " self.left = None\n",
" self.right = None\n", " self.right = None\n",
" self.parent = parent\n", " self.parent = parent\n",
" \n", "\n",
" def getElement(self,idx):\n", " def getElement(self, idx):\n",
" path=[]\n", " path = []\n",
" while(idx>0):\n", " while idx > 0:\n",
" if(idx%2==1):\n", " if idx % 2 == 1:\n",
" path.append((idx%2))\n", " path.append((idx % 2))\n",
" idx //= 2\n", " idx //= 2\n",
" else:\n", " else:\n",
" path.append((idx%2)+2)\n", " path.append((idx % 2) + 2)\n",
" idx = idx//2 -1\n", " idx = idx // 2 - 1\n",
" temp = self\n", " temp = self\n",
" while path and temp:\n", " while path and temp:\n",
" dr = path.pop()\n", " dr = path.pop()\n",
" if(dr==1):\n", " if dr == 1:\n",
" temp = temp.left\n", " temp = temp.left\n",
" else:\n", " else:\n",
" temp = temp.right\n", " temp = temp.right\n",
" if(temp):\n", " if temp:\n",
" return temp\n", " return temp\n",
" else:\n", " else:\n",
" print(\"id does not exists\")\n", " print(\"id does not exists\")\n",
" \n", "\n",
" def getDepth(self):\n", " def getDepth(self):\n",
" ld = self.left.getDepth() if self.left else -1\n", " ld = self.left.getDepth() if self.left else -1\n",
" rd = self.right.getDepth() if self.right else -1\n", " rd = self.right.getDepth() if self.right else -1\n",
" return max(ld,rd)+1\n", " return max(ld, rd) + 1\n",
"\n",
" def isBalanced(self):\n", " def isBalanced(self):\n",
" ld = self.left.getDepth() if self.left else -1\n", " ld = self.left.getDepth() if self.left else -1\n",
" rd= self.right.getDepth() if self.right else -1\n", " rd = self.right.getDepth() if self.right else -1\n",
" if(abs(ld-rd) in [0,1]):\n", " if abs(ld - rd) in [0, 1]:\n",
" lb = self.left.isBalanced() if self.left else True\n", " lb = self.left.isBalanced() if self.left else True\n",
" rb = self.right.isBalanced() if self.right else True\n", " rb = self.right.isBalanced() if self.right else True\n",
" return bool(lb*rb)\n", " return bool(lb * rb)\n",
" \n", "\n",
" def getParent(self):\n", " def getParent(self):\n",
" return self.parent\n", " return self.parent\n",
" \n", "\n",
" def getChilds(self):\n", " def getChilds(self):\n",
" return [self.left, self.right]\n", " return [self.left, self.right]\n",
" \n", "\n",
" def getId(self):\n", " def getId(self):\n",
" if(self.parent != None):\n", " if self.parent != None:\n",
" if(self == self.parent.left):\n", " if self == self.parent.left:\n",
" return self.parent.getId()*2 + 1\n", " return self.parent.getId() * 2 + 1\n",
" else:\n", " else:\n",
" return self.parent.getId()*2 + 2\n", " return self.parent.getId() * 2 + 2\n",
" else:\n", " else:\n",
" return 0\n", " return 0\n",
" \n", "\n",
" def __setattr__(self,key,value):\n", " def __setattr__(self, key, value):\n",
" self.__dict__[key] = value\n", " self.__dict__[key] = value\n",
" if(value):\n", " if value:\n",
" if(key in [\"left\", \"right\"]):\n", " if key in [\"left\", \"right\"]:\n",
" value.parent = self\n", " value.parent = self\n",
" \n", "\n",
" \n",
" def getSize(self):\n", " def getSize(self):\n",
" lsize = self.left.getSize() if self.left else 0\n", " lsize = self.left.getSize() if self.left else 0\n",
" rsize = self.right.getSize() if self.right else 0\n", " rsize = self.right.getSize() if self.right else 0\n",
" return lsize+1+rsize\n", " return lsize + 1 + rsize\n",
" \n", "\n",
" def addData(self, data, idx=-1):\n", " def addData(self, data, idx=-1):\n",
" if(idx==-1):\n", " if idx == -1:\n",
" q = [] \n", " q = []\n",
" q.append(self) \n", " q.append(self)\n",
" while (len(q)): \n", " while len(q):\n",
" temp = q[0] \n", " temp = q[0]\n",
" q.pop(0) \n", " q.pop(0)\n",
" if (not temp.left):\n", " if not temp.left:\n",
" temp.left = BTree(data, parent=temp) \n", " temp.left = BTree(data, parent=temp)\n",
" break\n", " break\n",
" else:\n", " else:\n",
" q.append(temp.left) \n", " q.append(temp.left)\n",
" if (not temp.right):\n", " if not temp.right:\n",
" temp.right = BTree(data, parent=temp)\n", " temp.right = BTree(data, parent=temp)\n",
" break\n", " break\n",
" else:\n", " else:\n",
" q.append(temp.right) \n", " q.append(temp.right)\n",
" else:\n", " else:\n",
" dr = idx%2\n", " dr = idx % 2\n",
" if(dr==1):\n", " if dr == 1:\n",
" ele = self.getElement(idx//2)\n", " ele = self.getElement(idx // 2)\n",
" ele.left = BTree(data, parent=ele)\n", " ele.left = BTree(data, parent=ele)\n",
" else:\n", " else:\n",
" ele = self.getElement(idx//2 -1)\n", " ele = self.getElement(idx // 2 - 1)\n",
" ele.right = BTree(data, parent=ele)\n", " ele.right = BTree(data, parent=ele)\n",
"\n",
" def addNode(self, node, idx=-1):\n", " def addNode(self, node, idx=-1):\n",
" if(idx==-1):\n", " if idx == -1:\n",
" q = [] \n", " q = []\n",
" q.append(self) \n", " q.append(self)\n",
" while (len(q)): \n", " while len(q):\n",
" temp = q[0] \n", " temp = q[0]\n",
" q.pop(0) \n", " q.pop(0)\n",
" if (not temp.left):\n", " if not temp.left:\n",
" temp.left = node \n", " temp.left = node\n",
" break\n", " break\n",
" else:\n", " else:\n",
" q.append(temp.left) \n", " q.append(temp.left)\n",
" if (not temp.right):\n", " if not temp.right:\n",
" temp.right = node\n", " temp.right = node\n",
" break\n", " break\n",
" else:\n", " else:\n",
" q.append(temp.right) \n", " q.append(temp.right)\n",
" \n", "\n",
" \n",
" \n",
" def traverse(self, order=\"pre\"):\n", " def traverse(self, order=\"pre\"):\n",
" ls = []\n", " ls = []\n",
" if(order==\"pre\"):\n", " if order == \"pre\":\n",
" ls.append(self.data)\n", " ls.append(self.data)\n",
" if(self.left):\n", " if self.left:\n",
" ls.extend(self.left.traverse(order))\n", " ls.extend(self.left.traverse(order))\n",
" if(self.right):\n", " if self.right:\n",
" ls.extend(self.right.traverse(order))\n", " ls.extend(self.right.traverse(order))\n",
" return ls\n", " return ls\n",
" elif(order==\"post\"):\n", " elif order == \"post\":\n",
" if(self.left):\n", " if self.left:\n",
" ls.extend(self.left.traverse(order))\n", " ls.extend(self.left.traverse(order))\n",
" if(self.right):\n", " if self.right:\n",
" ls.extend(self.right.traverse(order))\n", " ls.extend(self.right.traverse(order))\n",
" ls.append(self.data)\n", " ls.append(self.data)\n",
" return ls\n", " return ls\n",
" elif(order==\"in\"):\n", " elif order == \"in\":\n",
" if(self.left):\n", " if self.left:\n",
" ls.extend(self.left.traverse(order))\n", " ls.extend(self.left.traverse(order))\n",
" ls.append(self.data)\n", " ls.append(self.data)\n",
" if(self.right):\n", " if self.right:\n",
" ls.extend(self.right.traverse(order))\n", " ls.extend(self.right.traverse(order))\n",
" return ls" " return ls"
] ]
@ -619,14 +625,13 @@
], ],
"source": [ "source": [
"bt = BTree(0)\n", "bt = BTree(0)\n",
"bt.left=BTree(1)\n", "bt.left = BTree(1)\n",
"bt.right = BTree(2)\n", "bt.right = BTree(2)\n",
"bt.left.left = BTree(3)\n", "bt.left.left = BTree(3)\n",
"bt.left.right = BTree(4)\n", "bt.left.right = BTree(4)\n",
"bt.right.left = BTree(5)\n", "bt.right.left = BTree(5)\n",
"\n", "\n",
"\n", "\n",
"\n",
"# bt.getElement(5)\n", "# bt.getElement(5)\n",
"bt.traverse(\"post\")" "bt.traverse(\"post\")"
] ]
@ -650,7 +655,7 @@
], ],
"source": [ "source": [
"btr = BTree(3)\n", "btr = BTree(3)\n",
"ls=[5,6,8,11,4,14,9,17]\n", "ls = [5, 6, 8, 11, 4, 14, 9, 17]\n",
"for i in ls:\n", "for i in ls:\n",
" btr.addData(i)\n", " btr.addData(i)\n",
"btr.traverse(order=\"in\")\n", "btr.traverse(order=\"in\")\n",
@ -721,7 +726,7 @@
"btr.getElement(1).getId()\n", "btr.getElement(1).getId()\n",
"\n", "\n",
"\n", "\n",
"bt.getSize(),btr.getSize()" "bt.getSize(), btr.getSize()"
] ]
}, },
{ {

View File

@ -62,7 +62,8 @@
" return b\n", " return b\n",
" return eucld_gcd(b, r)\n", " return eucld_gcd(b, r)\n",
"\n", "\n",
"eucld_gcd(252,105)" "\n",
"eucld_gcd(252, 105)"
] ]
}, },
{ {
@ -85,6 +86,7 @@
"source": [ "source": [
"import numpy as np\n", "import numpy as np\n",
"\n", "\n",
"\n",
"def ext_eucld(a, b):\n", "def ext_eucld(a, b):\n",
" \"\"\"\n", " \"\"\"\n",
" Computes the extended Euclidean algorithm to find the greatest common divisor (GCD)\n", " Computes the extended Euclidean algorithm to find the greatest common divisor (GCD)\n",
@ -124,13 +126,14 @@
" ls = eucld(a, b)\n", " ls = eucld(a, b)\n",
" for i in ls:\n", " for i in ls:\n",
" row = np.append(row, [row[-2] - i * row[-1]], axis=0)\n", " row = np.append(row, [row[-2] - i * row[-1]], axis=0)\n",
" \n", "\n",
" if swap:\n", " if swap:\n",
" return list(row[-1])[::-1]\n", " return list(row[-1])[::-1]\n",
" \n", "\n",
" return list(row[-1])\n", " return list(row[-1])\n",
"\n", "\n",
"ext_eucld(97, 2)\n" "\n",
"ext_eucld(97, 2)"
] ]
}, },
{ {
@ -150,8 +153,8 @@
"source": [ "source": [
"a = 5\n", "a = 5\n",
"b = 7\n", "b = 7\n",
"gcd = eucld_gcd(a,b)\n", "gcd = eucld_gcd(a, b)\n",
"m,n = ext_eucld(a,b)\n", "m, n = ext_eucld(a, b)\n",
"print(f\"a={a}, b={b}, gcd={gcd}, m={m}, n={n}, ma+nb={m*a+n*b}\")" "print(f\"a={a}, b={b}, gcd={gcd}, m={m}, n={n}, ma+nb={m*a+n*b}\")"
] ]
}, },

View File

@ -49,124 +49,128 @@
"def id2bit(ls: list):\n", "def id2bit(ls: list):\n",
" \"\"\"\n", " \"\"\"\n",
" Converts a list of indices into a binary representation (bit vector).\n", " Converts a list of indices into a binary representation (bit vector).\n",
" \n", "\n",
" Given a list of indices (ls), this function returns a list of bits where \n", " Given a list of indices (ls), this function returns a list of bits where\n",
" the bit positions corresponding to the indices in the list are set to 1, \n", " the bit positions corresponding to the indices in the list are set to 1,\n",
" and all other positions are set to 0. The resulting list is reversed.\n", " and all other positions are set to 0. The resulting list is reversed.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" ls (list): A list of indices to be converted to bits.\n", " ls (list): A list of indices to be converted to bits.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: A list of bits representing the binary values.\n", " list: A list of bits representing the binary values.\n",
" \"\"\"\n", " \"\"\"\n",
" if(len(ls) == 0):\n", " if len(ls) == 0:\n",
" return [0, 0, 0, 0, 0, 0, 0, 0] # Return a default 8-bit array\n", " return [0, 0, 0, 0, 0, 0, 0, 0] # Return a default 8-bit array\n",
" aa = [0 for _ in range(max(ls) + 1)]\n", " aa = [0 for _ in range(max(ls) + 1)]\n",
" for i in ls:\n", " for i in ls:\n",
" aa[i] = 1\n", " aa[i] = 1\n",
" return aa[::-1]\n", " return aa[::-1]\n",
"\n", "\n",
"\n",
"def bit2id(ls: list, log=False):\n", "def bit2id(ls: list, log=False):\n",
" \"\"\"\n", " \"\"\"\n",
" Converts a binary list (bit vector) back to a list of indices.\n", " Converts a binary list (bit vector) back to a list of indices.\n",
" \n", "\n",
" Given a list of bits (ls), this function returns the indices of the bits\n", " Given a list of bits (ls), this function returns the indices of the bits\n",
" that are set to 1. The binary list is reversed during the conversion.\n", " that are set to 1. The binary list is reversed during the conversion.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" ls (list): A list of bits representing a binary value.\n", " ls (list): A list of bits representing a binary value.\n",
" log (bool, optional): Whether to log intermediate steps (default is False).\n", " log (bool, optional): Whether to log intermediate steps (default is False).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: A list of indices where the bits are set to 1.\n", " list: A list of indices where the bits are set to 1.\n",
" \"\"\"\n", " \"\"\"\n",
" ls = ls[::-1]\n", " ls = ls[::-1]\n",
" aa = []\n", " aa = []\n",
" \n", "\n",
" for i in range(len(ls)):\n", " for i in range(len(ls)):\n",
" if(ls[i] == 1):\n", " if ls[i] == 1:\n",
" aa.append(i)\n", " aa.append(i)\n",
" return aa[::-1]\n", " return aa[::-1]\n",
"\n", "\n",
"\n",
"def bit2mul(a, b, log=False):\n", "def bit2mul(a, b, log=False):\n",
" \"\"\"\n", " \"\"\"\n",
" Multiplies two binary numbers represented as lists of bits.\n", " Multiplies two binary numbers represented as lists of bits.\n",
" \n", "\n",
" This function multiplies two binary numbers by performing a bitwise \n", " This function multiplies two binary numbers by performing a bitwise\n",
" multiplication and addition over Galois Field (GF(2)).\n", " multiplication and addition over Galois Field (GF(2)).\n",
" \n", "\n",
" Args:\n", " Args:\n",
" a (list): A list of bits representing the first binary number.\n", " a (list): A list of bits representing the first binary number.\n",
" b (list): A list of bits representing the second binary number.\n", " b (list): A list of bits representing the second binary number.\n",
" log (bool, optional): Whether to log intermediate steps (default is False).\n", " log (bool, optional): Whether to log intermediate steps (default is False).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: The resulting binary number (list of bits).\n", " list: The resulting binary number (list of bits).\n",
" \"\"\"\n", " \"\"\"\n",
" ai = bit2id(a)\n", " ai = bit2id(a)\n",
" bi = bit2id(b)\n", " bi = bit2id(b)\n",
" a, b = a[::-1], b[::-1]\n", " a, b = a[::-1], b[::-1]\n",
" \n", "\n",
" if(ai == []):\n", " if ai == []:\n",
" return a\n", " return a\n",
" elif(bi == []):\n", " elif bi == []:\n",
" return b\n", " return b\n",
" \n", "\n",
" addn = [[ai[i] + bi[j] for j in range(len(bi))][::-1] for i in range(len(ai))][::-1]\n", " addn = [[ai[i] + bi[j] for j in range(len(bi))][::-1] for i in range(len(ai))][::-1]\n",
" addn = [id2bit(i) for i in addn]\n", " addn = [id2bit(i) for i in addn]\n",
" \n", "\n",
" maxsiz = max([len(i) for i in addn])\n", " maxsiz = max([len(i) for i in addn])\n",
" for i in range(len(addn)):\n", " for i in range(len(addn)):\n",
" if(len(addn[i]) < maxsiz):\n", " if len(addn[i]) < maxsiz:\n",
" addn[i] = [0 for _ in range(maxsiz - len(addn[i]))] + addn[i]\n", " addn[i] = [0 for _ in range(maxsiz - len(addn[i]))] + addn[i]\n",
" \n", "\n",
" smm = []\n", " smm = []\n",
" for i in range(maxsiz):\n", " for i in range(maxsiz):\n",
" t = 0\n", " t = 0\n",
" for j in addn:\n", " for j in addn:\n",
" t += j[i]\n", " t += j[i]\n",
" smm.append(t % 2)\n", " smm.append(t % 2)\n",
" \n", "\n",
" return smm\n", " return smm\n",
"\n", "\n",
"\n",
"def bit2add(a, b):\n", "def bit2add(a, b):\n",
" \"\"\"\n", " \"\"\"\n",
" Adds two binary numbers represented as lists of bits (bitwise addition).\n", " Adds two binary numbers represented as lists of bits (bitwise addition).\n",
" \n", "\n",
" This function adds two binary numbers by performing a bitwise addition over GF(2).\n", " This function adds two binary numbers by performing a bitwise addition over GF(2).\n",
" \n", "\n",
" Args:\n", " Args:\n",
" a (list): A list of bits representing the first binary number.\n", " a (list): A list of bits representing the first binary number.\n",
" b (list): A list of bits representing the second binary number.\n", " b (list): A list of bits representing the second binary number.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: The resulting binary number after addition (list of bits).\n", " list: The resulting binary number after addition (list of bits).\n",
" \"\"\"\n", " \"\"\"\n",
" a, b = list(a), list(b)\n", " a, b = list(a), list(b)\n",
" a, b = a[::-1], b[::-1]\n", " a, b = a[::-1], b[::-1]\n",
" maxsiz = max(len(a), len(b))\n", " maxsiz = max(len(a), len(b))\n",
" \n", "\n",
" if(len(a) < maxsiz):\n", " if len(a) < maxsiz:\n",
" a = a + [0 for _ in range(maxsiz - len(a))]\n", " a = a + [0 for _ in range(maxsiz - len(a))]\n",
" if(len(b) < maxsiz):\n", " if len(b) < maxsiz:\n",
" b = b + [0 for _ in range(maxsiz - len(b))]\n", " b = b + [0 for _ in range(maxsiz - len(b))]\n",
" \n", "\n",
" smm = []\n", " smm = []\n",
" for i in range(maxsiz):\n", " for i in range(maxsiz):\n",
" smm.append((a[i] + b[i]) % 2)\n", " smm.append((a[i] + b[i]) % 2)\n",
" \n", "\n",
" return smm[::-1]\n", " return smm[::-1]\n",
"\n", "\n",
"\n",
"def bit2str(bit: list):\n", "def bit2str(bit: list):\n",
" \"\"\"\n", " \"\"\"\n",
" Converts a list of bits into a string.\n", " Converts a list of bits into a string.\n",
" \n", "\n",
" This function converts a list of binary bits (0s and 1s) into a string of characters.\n", " This function converts a list of binary bits (0s and 1s) into a string of characters.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" bit (list): A list of bits (0s and 1s).\n", " bit (list): A list of bits (0s and 1s).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" str: The string representation of the binary bits.\n", " str: The string representation of the binary bits.\n",
" \"\"\"\n", " \"\"\"\n",
@ -175,100 +179,105 @@
" s += str(i)\n", " s += str(i)\n",
" return s\n", " return s\n",
"\n", "\n",
"\n",
"def str2bit(s: str):\n", "def str2bit(s: str):\n",
" \"\"\"\n", " \"\"\"\n",
" Converts a string of '0's and '1's into a list of bits.\n", " Converts a string of '0's and '1's into a list of bits.\n",
" \n", "\n",
" This function converts a string containing '0's and '1's into a list of integer bits.\n", " This function converts a string containing '0's and '1's into a list of integer bits.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" s (str): A string containing '0's and '1's.\n", " s (str): A string containing '0's and '1's.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: A list of bits (integers).\n", " list: A list of bits (integers).\n",
" \n", "\n",
" Raises:\n", " Raises:\n",
" ValueError: If the string contains characters other than '0' and '1'.\n", " ValueError: If the string contains characters other than '0' and '1'.\n",
" \"\"\"\n", " \"\"\"\n",
" if(set(s).issubset(set('01'))):\n", " if set(s).issubset(set(\"01\")):\n",
" bit = [int(i) for i in s]\n", " bit = [int(i) for i in s]\n",
" return bit\n", " return bit\n",
" else:\n", " else:\n",
" print(\"bit string should contain 1s and 0s\")\n", " print(\"bit string should contain 1s and 0s\")\n",
"\n", "\n",
"def modgf(dsr: list, dnt = [1, 0, 0, 0, 1, 1, 0, 1, 1]):\n", "\n",
"def modgf(dsr: list, dnt=[1, 0, 0, 0, 1, 1, 0, 1, 1]):\n",
" \"\"\"\n", " \"\"\"\n",
" Performs polynomial division over Galois Field (GF(2)).\n", " Performs polynomial division over Galois Field (GF(2)).\n",
"\n", "\n",
" This function divides the binary polynomial `dsr` by the binary polynomial `dnt`\n", " This function divides the binary polynomial `dsr` by the binary polynomial `dnt`\n",
" and returns the quotient and remainder.\n", " and returns the quotient and remainder.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" dsr (list): The dividend as a list of bits (binary polynomial).\n", " dsr (list): The dividend as a list of bits (binary polynomial).\n",
" dnt (list, optional): The divisor as a list of bits (default is a predefined irreducible polynomial).\n", " dnt (list, optional): The divisor as a list of bits (default is a predefined irreducible polynomial).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" tuple: The remainder and quotient as lists of bits.\n", " tuple: The remainder and quotient as lists of bits.\n",
" \"\"\"\n", " \"\"\"\n",
" dsr = bit2id(dsr)\n", " dsr = bit2id(dsr)\n",
" dnt = bit2id(dnt)\n", " dnt = bit2id(dnt)\n",
" qtnt = []\n", " qtnt = []\n",
" \n", "\n",
" while (len(dnt) != 0 and len(dsr) != 0 and (max(dnt) - max(dsr) >= 0)):\n", " while len(dnt) != 0 and len(dsr) != 0 and (max(dnt) - max(dsr) >= 0):\n",
" ml = max(dnt) - max(dsr)\n", " ml = max(dnt) - max(dsr)\n",
" qtnt.append(ml)\n", " qtnt.append(ml)\n",
" plus = id2bit(dnt)\n", " plus = id2bit(dnt)\n",
" minus = id2bit([ml + i for i in dsr])\n", " minus = id2bit([ml + i for i in dsr])\n",
" rem = bit2add(plus, minus)\n", " rem = bit2add(plus, minus)\n",
" dnt = bit2id(rem)\n", " dnt = bit2id(rem)\n",
" \n", "\n",
" return id2bit(dnt), id2bit(qtnt)\n", " return id2bit(dnt), id2bit(qtnt)\n",
"\n", "\n",
"\n",
"def ext_eucld(a, b, log=False):\n", "def ext_eucld(a, b, log=False):\n",
" \"\"\"\n", " \"\"\"\n",
" Extended Euclidean algorithm for binary polynomials.\n", " Extended Euclidean algorithm for binary polynomials.\n",
"\n", "\n",
" This function computes the extended Euclidean algorithm for binary polynomials `a` and `b`,\n", " This function computes the extended Euclidean algorithm for binary polynomials `a` and `b`,\n",
" returning the coefficients of the linear combination of `a` and `b` that equals the greatest common divisor (GCD).\n", " returning the coefficients of the linear combination of `a` and `b` that equals the greatest common divisor (GCD).\n",
" \n", "\n",
" Args:\n", " Args:\n",
" a (list): A list of bits representing the first binary polynomial.\n", " a (list): A list of bits representing the first binary polynomial.\n",
" b (list): A list of bits representing the second binary polynomial.\n", " b (list): A list of bits representing the second binary polynomial.\n",
" log (bool, optional): Whether to log intermediate steps (default is False).\n", " log (bool, optional): Whether to log intermediate steps (default is False).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: The coefficients of the linear combination of `a` and `b` (as lists of bits).\n", " list: The coefficients of the linear combination of `a` and `b` (as lists of bits).\n",
" \"\"\"\n", " \"\"\"\n",
" ai, bi = bit2id(a), bit2id(b)\n", " ai, bi = bit2id(a), bit2id(b)\n",
" if((len(ai) != 0 and len(bi) != 0)):\n", " if len(ai) != 0 and len(bi) != 0:\n",
" if(max(max(ai), max(bi)) == max(bi)):\n", " if max(max(ai), max(bi)) == max(bi):\n",
" a, b = b, a\n", " a, b = b, a\n",
" elif(len(ai) == 0 and len(bi) != 0):\n", " elif len(ai) == 0 and len(bi) != 0:\n",
" a, b = b, a\n", " a, b = b, a\n",
" \n", "\n",
" def eucld(a, b, log=False):\n", " def eucld(a, b, log=False):\n",
" a, b = a[::-1], b[::-1]\n", " a, b = a[::-1], b[::-1]\n",
" \n", "\n",
" if(set(b) == set([0]) or (b[0] == 1 and (set(b[1:]) == set([0])))):\n", " if set(b) == set([0]) or (b[0] == 1 and (set(b[1:]) == set([0]))):\n",
" return []\n", " return []\n",
" \n", "\n",
" ls = []\n", " ls = []\n",
" \n", "\n",
" while not (b[0] == 1 and (set(b[1:]) == set([0]))):\n", " while not (b[0] == 1 and (set(b[1:]) == set([0]))):\n",
" r, idx = modgf(b[::-1], dnt=a[::-1])\n", " r, idx = modgf(b[::-1], dnt=a[::-1])\n",
" r, idx = r[::-1], idx[::-1]\n", " r, idx = r[::-1], idx[::-1]\n",
" \n", "\n",
" if(set(r) == set([0])):\n", " if set(r) == set([0]):\n",
" return ls\n", " return ls\n",
" \n", "\n",
" ls.append(idx[::-1])\n", " ls.append(idx[::-1])\n",
" a = b\n", " a = b\n",
" b = r\n", " b = r\n",
" return ls\n", " return ls\n",
" \n", "\n",
" row = [[[0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0]],\n", " row = [\n",
" [[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1]]]\n", " [[0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0]],\n",
" \n", " [[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1]],\n",
" ]\n",
"\n",
" ls = eucld(a, b)\n", " ls = eucld(a, b)\n",
" for i in ls:\n", " for i in ls:\n",
" r10, r11 = row[-1][0], row[-1][1]\n", " r10, r11 = row[-1][0], row[-1][1]\n",
@ -277,32 +286,34 @@
" r1 = bit2add(r21, bit2mul(r11, i))\n", " r1 = bit2add(r21, bit2mul(r11, i))\n",
" rowl = [r0, r1]\n", " rowl = [r0, r1]\n",
" row.append(rowl)\n", " row.append(rowl)\n",
" \n", "\n",
" return row[-1]\n", " return row[-1]\n",
"\n", "\n",
"\n",
"def Gfinv(bit, irrpoly=[1, 0, 0, 0, 1, 1, 0, 1, 1]):\n", "def Gfinv(bit, irrpoly=[1, 0, 0, 0, 1, 1, 0, 1, 1]):\n",
" \"\"\"\n", " \"\"\"\n",
" Computes the multiplicative inverse of a binary polynomial over GF(2).\n", " Computes the multiplicative inverse of a binary polynomial over GF(2).\n",
" \n", "\n",
" This function uses the extended Euclidean algorithm to compute the inverse of a binary polynomial `bit`\n", " This function uses the extended Euclidean algorithm to compute the inverse of a binary polynomial `bit`\n",
" with respect to a predefined irreducible polynomial `irrpoly`.\n", " with respect to a predefined irreducible polynomial `irrpoly`.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" bit (list): A list of bits representing the binary polynomial to be inverted.\n", " bit (list): A list of bits representing the binary polynomial to be inverted.\n",
" irrpoly (list, optional): The irreducible polynomial used for the field (default is a predefined polynomial).\n", " irrpoly (list, optional): The irreducible polynomial used for the field (default is a predefined polynomial).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: The multiplicative inverse of the polynomial `bit` (list of bits).\n", " list: The multiplicative inverse of the polynomial `bit` (list of bits).\n",
" \"\"\"\n", " \"\"\"\n",
" if(set(bit) == set('0')):\n", " if set(bit) == set(\"0\"):\n",
" return '--'\n", " return \"--\"\n",
" \n", "\n",
" ans = ext_eucld(irrpoly, bit)\n", " ans = ext_eucld(irrpoly, bit)\n",
" ans = ans[-1][-len(bit):]\n", " ans = ans[-1][-len(bit) :]\n",
" return ans\n", " return ans\n",
"\n", "\n",
"\n",
"# Example call\n", "# Example call\n",
"Gfinv([0, 0, 0, 0, 0, 1, 0, 0], irrpoly=[0, 0, 0, 1, 0, 0, 1, 1])\n" "Gfinv([0, 0, 0, 0, 0, 1, 0, 0], irrpoly=[0, 0, 0, 1, 0, 0, 1, 1])"
] ]
}, },
{ {
@ -320,23 +331,23 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"def genmapping(n:int, irrpoly):\n", "def genmapping(n: int, irrpoly):\n",
" \"\"\"\n", " \"\"\"\n",
" Generates the elements of GF(2^n) and their corresponding multiplicative inverses \n", " Generates the elements of GF(2^n) and their corresponding multiplicative inverses\n",
" based on the provided irreducible polynomial.\n", " based on the provided irreducible polynomial.\n",
"\n", "\n",
" Parameters:\n", " Parameters:\n",
" n (int): The size of the Galois Field (GF(2^n)). Determines the number of elements \n", " n (int): The size of the Galois Field (GF(2^n)). Determines the number of elements\n",
" in the field, which is 2^n.\n", " in the field, which is 2^n.\n",
" irrpoly (list): A list of bits representing the irreducible polynomial used \n", " irrpoly (list): A list of bits representing the irreducible polynomial used\n",
" for the finite field operations (e.g., [1, 0, 0, 1] for x^3 + 1).\n", " for the finite field operations (e.g., [1, 0, 0, 1] for x^3 + 1).\n",
"\n", "\n",
" Returns:\n", " Returns:\n",
" tuple: A tuple containing:\n", " tuple: A tuple containing:\n",
" - gf (list): A list of binary strings of length `n`, representing all elements \n", " - gf (list): A list of binary strings of length `n`, representing all elements\n",
" of GF(2^n). The binary strings are padded with leading zeros.\n", " of GF(2^n). The binary strings are padded with leading zeros.\n",
" - invmap (dict): A dictionary mapping the index of each element in `gf` to the \n", " - invmap (dict): A dictionary mapping the index of each element in `gf` to the\n",
" index of its multiplicative inverse, using the irreducible \n", " index of its multiplicative inverse, using the irreducible\n",
" polynomial for the field.\n", " polynomial for the field.\n",
"\n", "\n",
" Example:\n", " Example:\n",
@ -345,24 +356,26 @@
" # invmap will contain a mapping of the inverses for each non-zero element.\n", " # invmap will contain a mapping of the inverses for each non-zero element.\n",
" \"\"\"\n", " \"\"\"\n",
" gf = [str(bin(i))[2:] for i in range(2**n)]\n", " gf = [str(bin(i))[2:] for i in range(2**n)]\n",
" \n", "\n",
" # Ensure each element has length n (pad with leading zeros if necessary)\n", " # Ensure each element has length n (pad with leading zeros if necessary)\n",
" for i in range(len(gf)):\n", " for i in range(len(gf)):\n",
" if len(gf[i]) < n:\n", " if len(gf[i]) < n:\n",
" gf[i] = '0' * (n - len(gf[i])) + gf[i]\n", " gf[i] = \"0\" * (n - len(gf[i])) + gf[i]\n",
" \n", "\n",
" # Create mappings: index -> element (key2ele) and element -> index (ele2key)\n", " # Create mappings: index -> element (key2ele) and element -> index (ele2key)\n",
" key2ele = dict(enumerate(gf))\n", " key2ele = dict(enumerate(gf))\n",
" ele2key = dict([i[::-1] for i in list(enumerate(gf))])\n", " ele2key = dict([i[::-1] for i in list(enumerate(gf))])\n",
" \n", "\n",
" # Generate the inverse map for all non-zero elements\n", " # Generate the inverse map for all non-zero elements\n",
" invmap = dict()\n", " invmap = dict()\n",
" for i in gf:\n", " for i in gf:\n",
" if set(i) != set('0'): # Skip zero element\n", " if set(i) != set(\"0\"): # Skip zero element\n",
" inv = bit2str(Gfinv(str2bit(i), irrpoly=irrpoly)) # Find the inverse of i\n", " inv = bit2str(Gfinv(str2bit(i), irrpoly=irrpoly)) # Find the inverse of i\n",
" invmap[ele2key[i]] = ele2key[inv] # Map the inverse using element-to-key mapping\n", " invmap[ele2key[i]] = ele2key[\n",
" \n", " inv\n",
" return gf, invmap\n" " ] # Map the inverse using element-to-key mapping\n",
"\n",
" return gf, invmap"
] ]
}, },
{ {
@ -372,7 +385,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"gf5,invmap = genmapping(n=5,irrpoly=id2bit([5,2,0]))" "gf5, invmap = genmapping(n=5, irrpoly=id2bit([5, 2, 0]))"
] ]
}, },
{ {
@ -393,7 +406,7 @@
} }
], ],
"source": [ "source": [
"set(invmap.values())==set(invmap.keys())" "set(invmap.values()) == set(invmap.keys())"
] ]
}, },
{ {
@ -464,15 +477,14 @@
"source": [ "source": [
"gf28 = [str(bin(i))[2:] for i in range(256)]\n", "gf28 = [str(bin(i))[2:] for i in range(256)]\n",
"for i in range(len(gf28)):\n", "for i in range(len(gf28)):\n",
" if(len(gf28[i])<8):\n", " if len(gf28[i]) < 8:\n",
" gf28[i] = '0'*(8-len(gf28[i])) + gf28[i]\n", " gf28[i] = \"0\" * (8 - len(gf28[i])) + gf28[i]\n",
"\n", "\n",
"key2ele = dict(enumerate(gf28))\n", "key2ele = dict(enumerate(gf28))\n",
"ele2key = dict([i[::-1] for i in list(enumerate(gf28))])\n", "ele2key = dict([i[::-1] for i in list(enumerate(gf28))])\n",
"invmap = dict()\n", "invmap = dict()\n",
"for i in gf28:\n", "for i in gf28:\n",
"\n", " if set(i) != set(\"0\"):\n",
" if(set(i)!=set('0')):\n",
" inv = bit2str(Gfinv(str2bit(i)))\n", " inv = bit2str(Gfinv(str2bit(i)))\n",
" invmap[ele2key[i]] = ele2key[inv]" " invmap[ele2key[i]] = ele2key[inv]"
] ]
@ -495,7 +507,7 @@
} }
], ],
"source": [ "source": [
"set(invmap.values())==set(invmap.keys())" "set(invmap.values()) == set(invmap.keys())"
] ]
}, },
{ {

View File

@ -45,16 +45,16 @@
"def id2bit(ls: list):\n", "def id2bit(ls: list):\n",
" \"\"\"\n", " \"\"\"\n",
" Converts a list of indices to a binary representation (bit array).\n", " Converts a list of indices to a binary representation (bit array).\n",
" \n", "\n",
" Given a list of indices, this function creates a binary list where each index in \n", " Given a list of indices, this function creates a binary list where each index in\n",
" the input list is set to 1 in the output list, and all other positions are set to 0. \n", " the input list is set to 1 in the output list, and all other positions are set to 0.\n",
" The output list is then reversed before returning.\n", " The output list is then reversed before returning.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" ls (list): A list of indices where each index will be set to 1 in the output list.\n", " ls (list): A list of indices where each index will be set to 1 in the output list.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: A list of binary values (0s and 1s), where each index in the input list corresponds \n", " list: A list of binary values (0s and 1s), where each index in the input list corresponds\n",
" to a 1 in the output binary list, and all other indices are 0.\n", " to a 1 in the output binary list, and all other indices are 0.\n",
" \"\"\"\n", " \"\"\"\n",
" if len(ls) == 0:\n", " if len(ls) == 0:\n",
@ -68,13 +68,13 @@
"def bit2id(ls: list):\n", "def bit2id(ls: list):\n",
" \"\"\"\n", " \"\"\"\n",
" Converts a binary list (bit array) to a list of indices where the value is 1.\n", " Converts a binary list (bit array) to a list of indices where the value is 1.\n",
" \n", "\n",
" This function iterates over the binary list and returns a list of indices where the binary value is 1.\n", " This function iterates over the binary list and returns a list of indices where the binary value is 1.\n",
" The list is reversed before returning.\n", " The list is reversed before returning.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" ls (list): A list of binary values (0s and 1s).\n", " ls (list): A list of binary values (0s and 1s).\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" list: A list of indices where the corresponding binary value in the input list is 1.\n", " list: A list of indices where the corresponding binary value in the input list is 1.\n",
" \"\"\"\n", " \"\"\"\n",
@ -89,13 +89,13 @@
"def XOR(*args):\n", "def XOR(*args):\n",
" \"\"\"\n", " \"\"\"\n",
" Performs bitwise XOR on a sequence of values.\n", " Performs bitwise XOR on a sequence of values.\n",
" \n", "\n",
" This function takes any number of arguments and performs the XOR operation iteratively \n", " This function takes any number of arguments and performs the XOR operation iteratively\n",
" across all the input values.\n", " across all the input values.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" *args: A sequence of values (typically integers) on which the XOR operation will be applied.\n", " *args: A sequence of values (typically integers) on which the XOR operation will be applied.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" int: The result of applying the XOR operation across all input values.\n", " int: The result of applying the XOR operation across all input values.\n",
" \"\"\"\n", " \"\"\"\n",
@ -108,26 +108,26 @@
"class LFSR:\n", "class LFSR:\n",
" \"\"\"\n", " \"\"\"\n",
" A class representing a Linear Feedback Shift Register (LFSR).\n", " A class representing a Linear Feedback Shift Register (LFSR).\n",
" \n", "\n",
" This class models an LFSR, which generates a sequence of bits based on an initial state \n", " This class models an LFSR, which generates a sequence of bits based on an initial state\n",
" and a feedback polynomial. The LFSR can be clocked to generate subsequent bits in the sequence.\n", " and a feedback polynomial. The LFSR can be clocked to generate subsequent bits in the sequence.\n",
" \n", "\n",
" Attributes:\n", " Attributes:\n",
" seq (list): The current state (bit sequence) of the LFSR.\n", " seq (list): The current state (bit sequence) of the LFSR.\n",
" taps (list): The positions of the taps used for feedback calculation.\n", " taps (list): The positions of the taps used for feedback calculation.\n",
" \n", "\n",
" Methods:\n", " Methods:\n",
" clock(): Shifts the bits in the LFSR and computes the new bit based on the feedback.\n", " clock(): Shifts the bits in the LFSR and computes the new bit based on the feedback.\n",
" \"\"\"\n", " \"\"\"\n",
" \n", "\n",
" def __init__(self, start, poly):\n", " def __init__(self, start, poly):\n",
" \"\"\"\n", " \"\"\"\n",
" Initializes an LFSR with a start state and a feedback polynomial.\n", " Initializes an LFSR with a start state and a feedback polynomial.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" start (list): The initial state of the LFSR, represented as a list of bits (0s and 1s).\n", " start (list): The initial state of the LFSR, represented as a list of bits (0s and 1s).\n",
" poly (list): A list representing the feedback polynomial, with 1s indicating the taps.\n", " poly (list): A list representing the feedback polynomial, with 1s indicating the taps.\n",
" \n", "\n",
" Raises:\n", " Raises:\n",
" ValueError: If the length of the start state does not match the polynomial length minus one.\n", " ValueError: If the length of the start state does not match the polynomial length minus one.\n",
" \"\"\"\n", " \"\"\"\n",
@ -140,8 +140,8 @@
" def clock(self):\n", " def clock(self):\n",
" \"\"\"\n", " \"\"\"\n",
" Advances the LFSR by one clock cycle.\n", " Advances the LFSR by one clock cycle.\n",
" \n", "\n",
" This method computes the feedback bit by XORing the bits at the tap positions, \n", " This method computes the feedback bit by XORing the bits at the tap positions,\n",
" shifts the state, and adds the feedback bit to the beginning of the sequence.\n", " shifts the state, and adds the feedback bit to the beginning of the sequence.\n",
" \"\"\"\n", " \"\"\"\n",
" feedback = XOR(*[self.seq[bit] for bit in self.taps])\n", " feedback = XOR(*[self.seq[bit] for bit in self.taps])\n",
@ -151,24 +151,24 @@
"class A51:\n", "class A51:\n",
" \"\"\"\n", " \"\"\"\n",
" A class representing the A5/1 stream cipher.\n", " A class representing the A5/1 stream cipher.\n",
" \n", "\n",
" A51 is a stream cipher used in GSM encryption. It combines three LFSRs and uses a majority rule \n", " A51 is a stream cipher used in GSM encryption. It combines three LFSRs and uses a majority rule\n",
" to control which LFSRs are clocked. The output is the XOR of the last bits of the LFSRs.\n", " to control which LFSRs are clocked. The output is the XOR of the last bits of the LFSRs.\n",
" \n", "\n",
" Attributes:\n", " Attributes:\n",
" lfsrs (list): A list of LFSR instances.\n", " lfsrs (list): A list of LFSR instances.\n",
" clock_bits (list): The bit positions used for clocking each LFSR.\n", " clock_bits (list): The bit positions used for clocking each LFSR.\n",
" lfsr_count (int): The number of LFSRs used in the cipher.\n", " lfsr_count (int): The number of LFSRs used in the cipher.\n",
" \n", "\n",
" Methods:\n", " Methods:\n",
" majority(*bits): Computes the majority bit from a list of bits.\n", " majority(*bits): Computes the majority bit from a list of bits.\n",
" clock(): Advances the cipher and returns the next bit of the keystream.\n", " clock(): Advances the cipher and returns the next bit of the keystream.\n",
" \"\"\"\n", " \"\"\"\n",
" \n", "\n",
" def __init__(self, lfsrs, clock_bits):\n", " def __init__(self, lfsrs, clock_bits):\n",
" \"\"\"\n", " \"\"\"\n",
" Initializes the A51 cipher with a list of LFSRs and their clocking bits.\n", " Initializes the A51 cipher with a list of LFSRs and their clocking bits.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" lfsrs (list): A list of LFSR instances used to generate the keystream.\n", " lfsrs (list): A list of LFSR instances used to generate the keystream.\n",
" clock_bits (list): A list indicating the bit positions in each LFSR to use for majority voting.\n", " clock_bits (list): A list indicating the bit positions in each LFSR to use for majority voting.\n",
@ -180,13 +180,13 @@
" def majority(self, *bits):\n", " def majority(self, *bits):\n",
" \"\"\"\n", " \"\"\"\n",
" Computes the majority bit from a sequence of bits.\n", " Computes the majority bit from a sequence of bits.\n",
" \n", "\n",
" This method determines the majority (1 or 0) from the given bits. If the number of 1s \n", " This method determines the majority (1 or 0) from the given bits. If the number of 1s\n",
" is greater than or equal to half of the number of LFSRs, the majority bit is 1; otherwise, it is 0.\n", " is greater than or equal to half of the number of LFSRs, the majority bit is 1; otherwise, it is 0.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" *bits: A sequence of bits (typically 0s and 1s) for which the majority is to be determined.\n", " *bits: A sequence of bits (typically 0s and 1s) for which the majority is to be determined.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" int: The majority bit (0 or 1).\n", " int: The majority bit (0 or 1).\n",
" \"\"\"\n", " \"\"\"\n",
@ -200,15 +200,17 @@
" def clock(self):\n", " def clock(self):\n",
" \"\"\"\n", " \"\"\"\n",
" Advances the A51 cipher by one clock cycle and generates the next keystream bit.\n", " Advances the A51 cipher by one clock cycle and generates the next keystream bit.\n",
" \n", "\n",
" This method computes the majority bit from the specified clocking positions of the LFSRs, \n", " This method computes the majority bit from the specified clocking positions of the LFSRs,\n",
" clocks the LFSRs if necessary, and outputs the XOR of the last bits of each LFSR as the next \n", " clocks the LFSRs if necessary, and outputs the XOR of the last bits of each LFSR as the next\n",
" bit of the keystream.\n", " bit of the keystream.\n",
" \n", "\n",
" Returns:\n", " Returns:\n",
" int: The next bit in the keystream generated by the A51 cipher.\n", " int: The next bit in the keystream generated by the A51 cipher.\n",
" \"\"\"\n", " \"\"\"\n",
" majority = self.majority(*[self.lfsrs[i].seq[self.clock_bits[i]] for i in range(self.lfsr_count)])\n", " majority = self.majority(\n",
" *[self.lfsrs[i].seq[self.clock_bits[i]] for i in range(self.lfsr_count)]\n",
" )\n",
" for i in range(self.lfsr_count):\n", " for i in range(self.lfsr_count):\n",
" if self.lfsrs[i].seq[self.clock_bits[i]] == majority:\n", " if self.lfsrs[i].seq[self.clock_bits[i]] == majority:\n",
" self.lfsrs[i].clock()\n", " self.lfsrs[i].clock()\n",
@ -224,7 +226,7 @@
"\n", "\n",
"# Generate a keystream of 10 bits\n", "# Generate a keystream of 10 bits\n",
"stream = [a51.clock() for i in range(10)]\n", "stream = [a51.clock() for i in range(10)]\n",
"stream\n" "stream"
] ]
}, },
{ {
@ -236,17 +238,18 @@
"source": [ "source": [
"import os\n", "import os\n",
"\n", "\n",
"\n",
"def write2txt_file(bitstream, filename):\n", "def write2txt_file(bitstream, filename):\n",
" \"\"\"\n", " \"\"\"\n",
" Writes a bitstream (string of '0's and '1's) to a text file.\n", " Writes a bitstream (string of '0's and '1's) to a text file.\n",
"\n", "\n",
" This function opens a text file in append mode and writes the provided bitstream to it.\n", " This function opens a text file in append mode and writes the provided bitstream to it.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" bitstream (str): A string of '0's and '1's representing the bitstream to be written.\n", " bitstream (str): A string of '0's and '1's representing the bitstream to be written.\n",
" filename (str): The path to the text file where the bitstream will be written.\n", " filename (str): The path to the text file where the bitstream will be written.\n",
" \"\"\"\n", " \"\"\"\n",
" with open(filename, 'a') as f: # Open in append mode to continue writing\n", " with open(filename, \"a\") as f: # Open in append mode to continue writing\n",
" f.write(bitstream)\n", " f.write(bitstream)\n",
"\n", "\n",
"\n", "\n",
@ -254,25 +257,25 @@
" \"\"\"\n", " \"\"\"\n",
" Writes a bitstream (string of '0's and '1's) to a binary file.\n", " Writes a bitstream (string of '0's and '1's) to a binary file.\n",
"\n", "\n",
" This function converts the bitstream into bytes, pads it to ensure it's a multiple of 8 bits, \n", " This function converts the bitstream into bytes, pads it to ensure it's a multiple of 8 bits,\n",
" and then writes it to a binary file in append mode.\n", " and then writes it to a binary file in append mode.\n",
" \n", "\n",
" Args:\n", " Args:\n",
" bitstream (str): A string of '0's and '1's representing the bitstream to be written.\n", " bitstream (str): A string of '0's and '1's representing the bitstream to be written.\n",
" filename (str): The path to the binary file where the bitstream will be written.\n", " filename (str): The path to the binary file where the bitstream will be written.\n",
" \"\"\"\n", " \"\"\"\n",
" byte_list = []\n", " byte_list = []\n",
" \n", "\n",
" # Pad the bitstream if it's not a multiple of 8\n", " # Pad the bitstream if it's not a multiple of 8\n",
" padding = (8 - (len(bitstream) % 8)) % 8\n", " padding = (8 - (len(bitstream) % 8)) % 8\n",
" bitstream += '0' * padding # Add extra '0's to make the length a multiple of 8\n", " bitstream += \"0\" * padding # Add extra '0's to make the length a multiple of 8\n",
" \n", "\n",
" for i in range(0, len(bitstream), 8):\n", " for i in range(0, len(bitstream), 8):\n",
" byte = bitstream[i:i+8]\n", " byte = bitstream[i : i + 8]\n",
" byte_list.append(int(byte, 2)) # Convert 8 bits to an integer (byte)\n", " byte_list.append(int(byte, 2)) # Convert 8 bits to an integer (byte)\n",
" \n", "\n",
" # Append the bytes to the binary file\n", " # Append the bytes to the binary file\n",
" with open(filename, 'ab') as f: # 'ab' mode to append to the binary file\n", " with open(filename, \"ab\") as f: # 'ab' mode to append to the binary file\n",
" f.write(bytearray(byte_list))\n", " f.write(bytearray(byte_list))\n",
"\n", "\n",
"\n", "\n",
@ -280,28 +283,30 @@
" \"\"\"\n", " \"\"\"\n",
" Generates a keystream using the A51 cipher and writes it to a file.\n", " Generates a keystream using the A51 cipher and writes it to a file.\n",
"\n", "\n",
" This function initializes the LFSRs based on the provided data, generates a keystream \n", " This function initializes the LFSRs based on the provided data, generates a keystream\n",
" using the A51 cipher, and writes the generated bits to a text file or binary file \n", " using the A51 cipher, and writes the generated bits to a text file or binary file\n",
" in chunks. It keeps track of the current size of the output file and prints progress \n", " in chunks. It keeps track of the current size of the output file and prints progress\n",
" at each 10% interval.\n", " at each 10% interval.\n",
"\n", "\n",
" Args:\n", " Args:\n",
" data (dict): A dictionary containing information about the LFSRs, including their \n", " data (dict): A dictionary containing information about the LFSRs, including their\n",
" start values, polynomials, and clock positions.\n", " start values, polynomials, and clock positions.\n",
" target_size (int): The target size of the file in bytes. The function will stop once \n", " target_size (int): The target size of the file in bytes. The function will stop once\n",
" this size is reached.\n", " this size is reached.\n",
" file_path (str): The path to the output file where the generated bitstream will be written.\n", " file_path (str): The path to the output file where the generated bitstream will be written.\n",
" \"\"\"\n", " \"\"\"\n",
" # Initialize the LFSRs and A51 cipher\n", " # Initialize the LFSRs and A51 cipher\n",
" lfsrs = [LFSR(start=i[\"start\"], poly=i[\"poly\"]) for i in data]\n", " lfsrs = [LFSR(start=i[\"start\"], poly=i[\"poly\"]) for i in data]\n",
" a51 = A51(lfsrs=lfsrs, clock_bits=[i[\"clock\"] for i in data])\n", " a51 = A51(lfsrs=lfsrs, clock_bits=[i[\"clock\"] for i in data])\n",
" \n", "\n",
" current_size = 0\n", " current_size = 0\n",
" bitstream_chunk = \"\" # Chunk of bits to write periodically\n", " bitstream_chunk = \"\" # Chunk of bits to write periodically\n",
" chunk_size = 10000 # Number of bits to generate at a time (can adjust for performance)\n", " chunk_size = (\n",
" 10000 # Number of bits to generate at a time (can adjust for performance)\n",
" )\n",
" progress_interval = target_size // 10 # 1/10th of the target size (100 MB)\n", " progress_interval = target_size // 10 # 1/10th of the target size (100 MB)\n",
" next_progress_checkpoint = progress_interval\n", " next_progress_checkpoint = progress_interval\n",
" \n", "\n",
" # Generate bits until the target file size is reached\n", " # Generate bits until the target file size is reached\n",
" while current_size < target_size:\n", " while current_size < target_size:\n",
" # Generate bits in chunks\n", " # Generate bits in chunks\n",
@ -310,17 +315,21 @@
"\n", "\n",
" # Write the chunk to file\n", " # Write the chunk to file\n",
" write2txt_file(bitstream_chunk, file_path)\n", " write2txt_file(bitstream_chunk, file_path)\n",
" \n", "\n",
" # Clear the chunk and update the current file size\n", " # Clear the chunk and update the current file size\n",
" bitstream_chunk = \"\"\n", " bitstream_chunk = \"\"\n",
" current_size = os.path.getsize(file_path)\n", " current_size = os.path.getsize(file_path)\n",
" \n", "\n",
" # Check if the file size has crossed the 1/10th checkpoint\n", " # Check if the file size has crossed the 1/10th checkpoint\n",
" if current_size >= next_progress_checkpoint:\n", " if current_size >= next_progress_checkpoint:\n",
" print(f\"File size crossed {round(next_progress_checkpoint / (1024 * 1024), 2)} MB\")\n", " print(\n",
" next_progress_checkpoint += progress_interval # Update to next 10% checkpoint\n", " f\"File size crossed {round(next_progress_checkpoint / (1024 * 1024), 2)} MB\"\n",
" )\n",
" next_progress_checkpoint += (\n",
" progress_interval # Update to next 10% checkpoint\n",
" )\n",
"\n", "\n",
" print(f\"File generation complete: {file_path} (target)\")\n" " print(f\"File generation complete: {file_path} (target)\")"
] ]
}, },
{ {
@ -342,9 +351,9 @@
"data = [\n", "data = [\n",
" {\"start\": [0, 1, 0, 1, 1], \"poly\": id2bit([5, 2, 0]), \"clock\": 2},\n", " {\"start\": [0, 1, 0, 1, 1], \"poly\": id2bit([5, 2, 0]), \"clock\": 2},\n",
" {\"start\": [1, 0, 0, 1, 0], \"poly\": id2bit([5, 4, 3, 1, 0]), \"clock\": 3},\n", " {\"start\": [1, 0, 0, 1, 0], \"poly\": id2bit([5, 4, 3, 1, 0]), \"clock\": 3},\n",
" {\"start\": [0, 1, 1, 0, 0], \"poly\": id2bit([5, 4, 2, 1, 0]), \"clock\": 2}\n", " {\"start\": [0, 1, 1, 0, 0], \"poly\": id2bit([5, 4, 2, 1, 0]), \"clock\": 2},\n",
"]\n", "]\n",
"gen_bit_stream(data, target_size=1*1024**2, file_path=\"mine_gen_100MB.txt\")" "gen_bit_stream(data, target_size=1 * 1024**2, file_path=\"mine_gen_100MB.txt\")"
] ]
}, },
{ {

View File

@ -35,7 +35,7 @@
" \"\"\"\n", " \"\"\"\n",
" PlayFire class implements the Playfair cipher for encryption and decryption of messages.\n", " PlayFire class implements the Playfair cipher for encryption and decryption of messages.\n",
"\n", "\n",
" The Playfair cipher is a digraph substitution cipher that encrypts pairs of letters. It requires a key, which \n", " The Playfair cipher is a digraph substitution cipher that encrypts pairs of letters. It requires a key, which\n",
" is used to create a 6x6 matrix of letters and digits, and processes the message in pairs.\n", " is used to create a 6x6 matrix of letters and digits, and processes the message in pairs.\n",
"\n", "\n",
" Attributes:\n", " Attributes:\n",
@ -51,7 +51,7 @@
" decrypt(msg): Decrypts the given encrypted message using the Playfair cipher.\n", " decrypt(msg): Decrypts the given encrypted message using the Playfair cipher.\n",
" \"\"\"\n", " \"\"\"\n",
"\n", "\n",
" def __init__(self, key, extra='x'):\n", " def __init__(self, key, extra=\"x\"):\n",
" \"\"\"\n", " \"\"\"\n",
" Initializes the PlayFire cipher with a key and an optional extra character for padding.\n", " Initializes the PlayFire cipher with a key and an optional extra character for padding.\n",
"\n", "\n",
@ -75,9 +75,9 @@
" \"\"\"\n", " \"\"\"\n",
" keyy = []\n", " keyy = []\n",
" for i in key:\n", " for i in key:\n",
" if(i not in keyy):\n", " if i not in keyy:\n",
" keyy.append(i)\n", " keyy.append(i)\n",
" if(len(set(key)) == len(key)):\n", " if len(set(key)) == len(key):\n",
" return key\n", " return key\n",
" else:\n", " else:\n",
" print(\"key Error\")\n", " print(\"key Error\")\n",
@ -95,7 +95,7 @@
" mtrx = []\n", " mtrx = []\n",
" idx = 0\n", " idx = 0\n",
" for i in range(6):\n", " for i in range(6):\n",
" t1 = xx[idx:idx + 6]\n", " t1 = xx[idx : idx + 6]\n",
" mtrx.append(t1)\n", " mtrx.append(t1)\n",
" idx = idx + 6\n", " idx = idx + 6\n",
" return mtrx\n", " return mtrx\n",
@ -113,13 +113,13 @@
" idxs = [6, 6]\n", " idxs = [6, 6]\n",
" for i in range(6):\n", " for i in range(6):\n",
" for j in range(6):\n", " for j in range(6):\n",
" if(i == 5):\n", " if i == 5:\n",
" i = -1\n", " i = -1\n",
" if(j == 5):\n", " if j == 5:\n",
" j = -1\n", " j = -1\n",
" if(pair[0] == self.key_matrix[i][j]):\n", " if pair[0] == self.key_matrix[i][j]:\n",
" idxs[0] = [i, j]\n", " idxs[0] = [i, j]\n",
" if(pair[1] == self.key_matrix[i][j]):\n", " if pair[1] == self.key_matrix[i][j]:\n",
" idxs[1] = [i, j]\n", " idxs[1] = [i, j]\n",
" return idxs\n", " return idxs\n",
"\n", "\n",
@ -134,20 +134,29 @@
" str: The encrypted message.\n", " str: The encrypted message.\n",
" \"\"\"\n", " \"\"\"\n",
" msg = list(msg.lower())\n", " msg = list(msg.lower())\n",
" if(len(msg) % 2 == 1):\n", " if len(msg) % 2 == 1:\n",
" msg.append(self.extra)\n", " msg.append(self.extra)\n",
" pairs = []\n", " pairs = []\n",
" for i in range(0, len(msg), 2):\n", " for i in range(0, len(msg), 2):\n",
" pairs.append(msg[i:i + 2])\n", " pairs.append(msg[i : i + 2])\n",
" en_msg = \"\"\n", " en_msg = \"\"\n",
" for i in pairs:\n", " for i in pairs:\n",
" idxs = self.find_idx(i)\n", " idxs = self.find_idx(i)\n",
" if(idxs[0][0] == idxs[1][0]):\n", " if idxs[0][0] == idxs[1][0]:\n",
" en_m = self.key_matrix[idxs[0][0]][idxs[0][1] + 1] + self.key_matrix[idxs[0][0]][idxs[1][1] + 1]\n", " en_m = (\n",
" elif(idxs[0][1] == idxs[1][1]):\n", " self.key_matrix[idxs[0][0]][idxs[0][1] + 1]\n",
" en_m = self.key_matrix[idxs[0][0] + 1][idxs[0][1]] + self.key_matrix[idxs[1][0] + 1][idxs[1][1]]\n", " + self.key_matrix[idxs[0][0]][idxs[1][1] + 1]\n",
" )\n",
" elif idxs[0][1] == idxs[1][1]:\n",
" en_m = (\n",
" self.key_matrix[idxs[0][0] + 1][idxs[0][1]]\n",
" + self.key_matrix[idxs[1][0] + 1][idxs[1][1]]\n",
" )\n",
" else:\n", " else:\n",
" en_m = self.key_matrix[idxs[0][0]][idxs[1][1]] + self.key_matrix[idxs[1][0]][idxs[0][1]]\n", " en_m = (\n",
" self.key_matrix[idxs[0][0]][idxs[1][1]]\n",
" + self.key_matrix[idxs[1][0]][idxs[0][1]]\n",
" )\n",
" en_msg += en_m\n", " en_msg += en_m\n",
" return en_msg\n", " return en_msg\n",
"\n", "\n",
@ -162,22 +171,31 @@
" str: The decrypted plaintext message.\n", " str: The decrypted plaintext message.\n",
" \"\"\"\n", " \"\"\"\n",
" msg = list(msg.lower())\n", " msg = list(msg.lower())\n",
" if(len(msg) % 2 == 1):\n", " if len(msg) % 2 == 1:\n",
" msg.append(self.extra)\n", " msg.append(self.extra)\n",
" pairs = []\n", " pairs = []\n",
" for i in range(0, len(msg), 2):\n", " for i in range(0, len(msg), 2):\n",
" pairs.append(msg[i:i + 2])\n", " pairs.append(msg[i : i + 2])\n",
" en_msg = \"\"\n", " en_msg = \"\"\n",
" for i in pairs:\n", " for i in pairs:\n",
" idxs = self.find_idx(i)\n", " idxs = self.find_idx(i)\n",
" if(idxs[0][0] == idxs[1][0]):\n", " if idxs[0][0] == idxs[1][0]:\n",
" en_m = self.key_matrix[idxs[0][0]][idxs[0][1] - 1] + self.key_matrix[idxs[0][0]][idxs[1][1] - 1]\n", " en_m = (\n",
" elif(idxs[0][1] == idxs[1][1]):\n", " self.key_matrix[idxs[0][0]][idxs[0][1] - 1]\n",
" en_m = self.key_matrix[idxs[0][0] - 1][idxs[0][1]] + self.key_matrix[idxs[1][0] - 1][idxs[1][1]]\n", " + self.key_matrix[idxs[0][0]][idxs[1][1] - 1]\n",
" )\n",
" elif idxs[0][1] == idxs[1][1]:\n",
" en_m = (\n",
" self.key_matrix[idxs[0][0] - 1][idxs[0][1]]\n",
" + self.key_matrix[idxs[1][0] - 1][idxs[1][1]]\n",
" )\n",
" else:\n", " else:\n",
" en_m = self.key_matrix[idxs[0][0]][idxs[1][1]] + self.key_matrix[idxs[1][0]][idxs[0][1]]\n", " en_m = (\n",
" self.key_matrix[idxs[0][0]][idxs[1][1]]\n",
" + self.key_matrix[idxs[1][0]][idxs[0][1]]\n",
" )\n",
" en_msg += en_m\n", " en_msg += en_m\n",
" return en_msg\n" " return en_msg"
] ]
}, },
{ {
@ -225,7 +243,7 @@
} }
], ],
"source": [ "source": [
"msg = 'hello1234'\n", "msg = \"hello1234\"\n",
"enc = pf.encrypt(msg)\n", "enc = pf.encrypt(msg)\n",
"enc" "enc"
] ]
@ -290,7 +308,7 @@
} }
], ],
"source": [ "source": [
"pf.decrypt(pf.encrypt('r'))" "pf.decrypt(pf.encrypt(\"r\"))"
] ]
}, },
{ {