数値型の派生として GF(2) 用のクラスをざっくりと作ってみた。
修正した方がいいところが多少あると思います。
GF2.py
import numbers
class GF2(numbers.Integral):
# int 値を取得
@staticmethod
def ToInt(other):
if type(other) == int:
return other
if type(other) == GF2:
return other.value
if type(other) == str:
return int(other, 2)
raise NotImplemented
# 初期化
def __init__(self, value):
self.value = GF2.ToInt(value)
# 変換
def __int__(self): return self.value
def __repr__(self): return bin(self.value)[2:]
def __str__(self): return bin(self.value)[2:]
# 比較
def __eq__(self, other): return self.value == GF2.ToInt(other)
def __lt__(self, other): raise NotImplemented
def __le__(self, other): raise NotImplemented
# 単項演算
def __neg__(self): return GF2(self)
def __pos__(self): return GF2(self)
def __invert__(self): return GF2(self)
# 二項演算:算術
def __add__(self, other): return GF2(self.value ^ GF2.ToInt(other))
def __sub__(self, other): return GF2(self.value ^ GF2.ToInt(other))
def __mul__(self, other): return GF2(self.mul(other))
def __pow__(self, other): return GF2(self.pow(other))
def __divmod__(self, other): return tuple([GF2(v) for v in self.divmod(other)])
def __truediv__(self, other): return GF2(self.div(other))
def __floordiv__(self, other): return GF2(self.div(other))
def __mod__(self, other): return GF2(self.mod(other))
# 二項演算:論理
def __and__(self, other): return GF2(self.value & GF2.ToInt(other))
def __xor__(self, other): return GF2(self.value ^ GF2.ToInt(other))
def __or__(self, other): return GF2(self.value | GF2.ToInt(other))
def __lshift__(self, other): return GF2(self.value << GF2.ToInt(other))
def __rshift__(self, other): return GF2(self.value << GF2.ToInt(other))
# 二項演算:右項
def __radd__(self, other): return GF2(self.value ^ GF2.ToInt(other))
def __rsub__(self, other): return GF2(self.value ^ GF2.ToInt(other))
def __rmul__(self, other): return GF2(other) * self
def __rmod__(self, other): return GF2(other) % self
def __rtruediv__(self, other): return GF2(other) / self
def __rfloordiv__(self, other): return GF2(other) // self
def __rpow__(self, other): return GF2(other) ** self
def __rand__(self, other): return GF2(self.value & GF2.ToInt(other))
def __rxor__(self, other): return GF2(self.value ^ GF2.ToInt(other))
def __ror__(self, other): return GF2(self.value | GF2.ToInt(other))
def __rlshift__(self, other): return GF2(GF2.ToInt(other) << self.value)
def __rrshift__(self, other): return GF2(GF2.ToInt(other) << self.value)
# 二項演算:更新
def __iadd__(self, other):
self.value ^= GF2.ToInt(other)
return self
def __isub__(self, other):
self.value ^= GF2.ToInt(other)
return self
def __imul__(self, other):
self.value = self.mul(other)
return self
def __itruediv__(self, other):
self.value = self.div(other)
return self
def __imod__(self, other):
self.value = self.mod(other)
return self
# 組み込み
def __abs__(self): return GF2(self)
def __ceil__(self): return GF2(self)
def __floor__(self): return GF2(self)
def __round__(self): return GF2(self)
def __trunc__(self): return GF2(self)
# 積
def mul(self, other):
a = self.value
b = GF2.ToInt(other)
r = 0
while b != 0:
if (b & 1) != 0:
r ^= a
a <<= 1
b >>= 1
return r
# 商
def divmod(self, other):
a = self.value
b = GF2.ToInt(other)
alen = a.bit_length()
blen = b.bit_length()
rlen = alen - blen
if rlen < 0:
return (0, a)
b <<= rlen
c = (1 << (alen - 1))
r = 0
for n in range(rlen + 1):
r <<= 1
if (a & c) != 0:
a ^= b
r |= 1
b >>= 1
c >>= 1
return (r, a)
def div(self, other):
return self.divmod(other)[0]
def mod(self, other):
return self.divmod(other)[1]
# 冪
def pow(self, other):
a = self.value
b = GF2.ToInt(other)
r = GF2(a)
for n in range(b - 1):
r *= a
return r
テスト
>>> a = GF2(0b100011101)
>>> print(a + a)
0
>>> print(a - a)
0
>>> print(a * a)
10000000101010001
>>> print(a / a)
1
>>> print(a // a)
1
>>> print(a % a)
0
>>> print(a ** 2)
10000000101010001
>>>
>>> print(0 + a)
100011101
>>> print(0b11101 - a)
100000000
>>> print(0b11101 * a)
1110001010001
>>> print(0b11101 / a)
0
>>> print(0b11101 // a)
0
>>> print(0b11101 % a)
11101
>>> print(0b1100011101 / a)
11
>>> print(0b1100011101 % a)
111010