Re: 難易度

人物: ArtForz

これが Python 向けの俺の手早く雑な参照実装だ。-256〜256 の範囲と、8〜256 ビットでサイズの異なるランダムな数値約 4000個について、Bitcoin の実装と照らし合わせてテスト済みだ。 もっと速く Python らしいバージョンを書くのは簡単なはずだが、今はその気になれない…

import struct

def mpi2num(m):
	"""convert MPI string to number"""
	datasize = struct.unpack(">I", m[0:4])[0]
	r = 0
	if datasize:
		neg_flag = bool(ord(m[4]) & 0x80)
		r = ord(m[4]) & 0x7F
		for i in xrange(1, datasize):
			r <<= 8
			r += ord(m[4+i])
		if neg_flag:
			r = -r
	return r

def num2mpi(n):
	"""convert number to MPI string"""
	if n == 0:
		return struct.pack(">I", 0)
	r = ""
	neg_flag = bool(n < 0)
	n = abs(n)
	while n:
		r = chr(n & 0xFF) + r
		n >>= 8
	if ord(r[0]) & 0x80:
		r = chr(0) + r
	if neg_flag:
		r = chr(ord(r[0]) | 0x80) + r[1:]
	datasize = len(r)
	return struct.pack(">I", datasize) + r

def GetCompact(n):
	"""convert number to bc compact uint"""
	mpi = num2mpi(n)
	nSize = len(mpi) - 4
	nCompact = (nSize & 0xFF) << 24
	if nSize >= 1:
		nCompact |= (ord(mpi[4]) << 16)
	if nSize >= 2:
		nCompact |= (ord(mpi[5]) << 8)
	if nSize >= 3:
		nCompact |= (ord(mpi[6]) << 0)
	return nCompact

def SetCompact(nCompact):
	"""convert bc compact uint to number"""
	nSize = (nCompact >> 24) & 0xFF
	tbuf = "\x00\x00\x00" + chr(nSize)
	if nSize >= 1:
		tbuf += chr((nCompact >> 16) & 0xFF)
	if nSize >= 2:
		tbuf += chr((nCompact >> 8) & 0xFF)
	if nSize >= 3:
		tbuf += chr((nCompact >> 0) & 0xFF)
		tbuf += "\x00" * (nSize - 3)
	return mpi2num(tbuf)