<p><strong>警告:</strong>该线程的原始解决方案来自@Matthew McPeak,这是应该得到奖励的答案,下面您会发现一个稍微修改的版本,其中我为他的算法添加了一些重构:</p>
<pre><code>import math
import decimal
import hashlib
def to_oracle_number(nstr):
n = decimal.Decimal(nstr)
# compute exponent (base 100) and convert to Oracle byte along with sign
l_exp, l_len, l_abs_n = 0, 0, abs(n)
if l_abs_n != 0:
l_exp = math.floor(math.log(l_abs_n, 100)) + 65
l_exp = (l_exp ^ 127) if n < 0 else l_exp + 128
l_bytes = [l_exp]
l_len += 1 # exponent and sign take 1 byte
l_whole_part = str(int(l_abs_n))
# make sure there is an even number of digits in the whole part
if len(l_whole_part) % 2 == 1:
l_whole_part = '0' + l_whole_part
# get the fractional digits, so if 0.01234, just 01234
l_frac_part = str(l_abs_n - int(l_abs_n))[2:]
# make sure there is an even number of digits in the fractional part
if len(l_frac_part) % 2 == 1:
l_frac_part += '0'
l_mantissa = l_whole_part + l_frac_part
# chop off leading 00 pairs
while l_mantissa[0:2] == '00':
l_mantissa = l_mantissa[2:]
# chop off trailing 00 pairs
while l_mantissa[-2:] == '00':
l_mantissa = l_mantissa[:-2]
# compute number of 2-character chunks
l_chunks = ''
for i in range(0, int(len(l_mantissa) / 2)):
l_chunk = int(l_mantissa[i * 2:i * 2 + 2])
if n < 0:
l_chunk = 100 - l_chunk
l_chunk += 1
l_chunks = f"{l_chunks},l_chunk"
l_bytes.append(l_chunk)
l_len += 1
if n < 0 and l_len < 21:
# terminating negative numbers always end in byte 102 (do not know why)
l_chunks += ',102'
l_bytes.append(102)
l_len += 1
# bytes(l_bytes)l_computed_dump = f"Typ=2 Len={l_len}: {l_exp}{l_chunks}"
m = hashlib.sha256()
m.update(bytes(l_bytes))
return m.hexdigest().upper()
if __name__ == '__main__':
assert to_oracle_number('123') == "A0740C0829EC3314E5318E1F060266479AA31F8BBBC1868DA42B9E608F52A09F"
</code></pre>