python - AttributeError: 'str' object has no attribute 'decode'. Could not find anywhere
问题描述
The conversion from py2 to py3 gave this error and could not find anywhere. In line 242 is the error. Below the code that calls it.
ERROR:
Traceback (most recent call last):
File "CHAMADA_KECCAK.py", line 51, in <module> f = g.funcao()
File "CHAMADA_KECCAK.py", line 46, in funcao y = x.sha3_256(t).digest()
File "C:\Users\asus\Desktop\UENF\11 PERIODO\MONOGRAFIA ARTHUR EM ANDAMENTO\python_sha3.py", line 242, in digest
M = _build_message_pair(self.buffered_data.decode('hex'))
AttributeError: 'str' object has no attribute 'decode'
Code: CHAMADA_KECCAK.py
import python_sha3
class principal:
def funcao(self):
t = 'arthurrieofkmdslmvdsmveribmfkdbdfmbero'
x = python_sha3
y = x.sha3_256(t).digest()
return y
print ("\nO hash Keccak-256 do texto: \n %s \nEh:\n %s"%(t , y))
g = principal()
f = g.funcao()
Code: python_sha3.py
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import math
def sha3_256(data=None):
return Keccak(c=512, r=1088, n=256, data=data)
class KeccakError(Exception):
#Classe de erro personalizada usada na implementacao do Keccak
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class Keccak:
def __init__(self, r, c, n, data=None):
# Inicialize as constantes usadas em todo o Keccak
# taxa de bits
self.r = r
# capacidade
self.c = c
# tamanho da saida
self.n = n
self.b = r + c
# b = 25*w
self.w = self.b // 25
# 2**l = w
self.l = int(math.log(self.w, 2))
self.n_r = 12 + 2 * self.l
self.block_size = r
self.digest_size = n
# Inicialize o estado da esponja
# O estado eh composto por 25 palavras, cada palavra sendo w bits.
self.S =[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
# Uma sequencia de hexchars, em que cada caractere representa 4 bits.
self.buffered_data = ""
# Armazene o resumo calculado.
# Apenas aplicaremos preenchimento e recalcularemos o hash se ele for modificado.
self.last_digest = None
if data:
self.update(data)
# Constantes
# # Constantes redondas
RC = [0x0000000000000001,
0x0000000000008082,
0x800000000000808A,
0x8000000080008000,
0x000000000000808B,
0x0000000080000001,
0x8000000080008081,
0x8000000000008009,
0x000000000000008A,
0x0000000000000088,
0x0000000080008009,
0x000000008000000A,
0x000000008000808B,
0x800000000000008B,
0x8000000000008089,
0x8000000000008003,
0x8000000000008002,
0x8000000000000080,
0x000000000000800A,
0x800000008000000A,
0x8000000080008081,
0x8000000000008080,
0x0000000080000001,
0x8000000080008008]
## Deslocamentos de rotacao
r = [[0, 36, 3, 41, 18],
[1, 44, 10, 45, 2],
[62, 6, 43, 15, 61],
[28, 55, 25, 21, 56],
[27, 20, 39, 8, 14]]
@staticmethod
def Round(A, RCfixed, w):
"""Execute uma rodada de calculo conforme definido na permutacao Keccak-f
A: estado atual (matriz 5x5)
RCfixed: valor da constante arredondada a ser usada (inteiro)"""
#Inicializacao de variaveis temporarias
B = [[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
C = [0, 0, 0, 0, 0]
D = [0, 0, 0, 0, 0]
#Etapa Theta
for x in range(5):
C[x] = A[x][0] ^ A[x][1] ^ A[x][2] ^ A[x][3] ^ A[x][4]
for x in range(5):
D[x] = C[(x - 1) % 5] ^ _rot(C[(x + 1) % 5], 1, w)
for x in range(5):
for y in range(5):
A[x][y] = A[x][y] ^ D[x]
#Etapa Rho e Pi
for x in range(5):
for y in range(5):
B[y][(2 * x + 3 * y) % 5] = _rot(A[x][y], Keccak.r[x][y], w)
#Etapa Chi
for x in range(5):
for y in range(5):
A[x][y] = B[x][y] ^ ((~B[(x + 1) % 5][y]) & B[(x + 2) % 5][y])
#Etapa Iota
A[0][0] = A[0][0] ^ RCfixed
return A
@staticmethod
def KeccakF(A, n_r, w):
"""Execute a funcao Keccak-f no estado A
A: matriz 5x5 contendo o estado, em que cada entrada eh uma sequencia de hexchars com 'w' bits de comprimento
n_r: numero de rodadas
w: tamanho da palavra
"""
for i in xrange(n_r):
A = Keccak.Round(A, Keccak.RC[i] % (1 << w), w)
# print (A)
return A
### Regra de preenchimento
@staticmethod
def pad10star1(M, n):
"""PAD M com a regra de preenchimento pad10 * 1 para atingir um comprimento multiplo de r bits
M: par de mensagens (comprimento em bits, sequencia de caracteres hexadecimais ('9AFC ...')
n: comprimento em bits (deve ser multiplo de 8)
Exemplo: pad10star1 ([60, 'BA594E0FB9EBBD30'], 8) retorna 'BA594E0FB9EBBD93'
"""
[my_string_length, my_string] = M
# Verifique o parametro n
if n % 8 != 0:
raise KeccakError.KeccakError("n deve ser um multiplo de 8")
# Verifique o comprimento da string fornecida
if len(my_string) % 2 != 0:
#Pad com um '0' para atingir o comprimento correto (nao sei codificacao de vetores de teste)
my_string += '0'
if my_string_length > (len(my_string) // 2 * 8):
raise KeccakError.KeccakError("A cadeia eh muito curta para conter o numero de bits anunciados")
nr_bytes_filled = my_string_length // 8
nbr_bits_filled = my_string_length % 8
l = my_string_length % n
if ((n - 8) <= l <= (n - 2)):
if (nbr_bits_filled == 0):
my_byte = 0
else:
my_byte = int(my_string[nr_bytes_filled * 2:nr_bytes_filled * 2 + 2], 16)
my_byte = (my_byte >> (8 - nbr_bits_filled))
my_byte = my_byte + 2 ** (nbr_bits_filled) + 2 ** 7
my_byte = "%02X" % my_byte
my_string = my_string[0:nr_bytes_filled * 2] + my_byte
else:
if (nbr_bits_filled == 0):
my_byte = 0
else:
my_byte = int(my_string[nr_bytes_filled * 2:nr_bytes_filled * 2 + 2], 16)
my_byte = (my_byte >> (8 - nbr_bits_filled))
my_byte = my_byte + 2 ** (nbr_bits_filled)
my_byte = "%02X" % my_byte
my_string = my_string[0:nr_bytes_filled * 2] + my_byte
while((8 * len(my_string) // 2) % n < (n - 8)):
my_string = my_string + '00'
my_string = my_string + '80'
# print (my_string)
return my_string
def update(self, arg):
"""Atualize o objeto hash com a string arg. Chamadas repetidas sao equivalentes a
uma unica chamada com a concatenacao de todos os argumentos: m.update (a);
m.update (b) eh equivalente a m.update (a + b). arg eh um bytestring normal.
"""
self.last_digest = None
# Converta os dados em um formato viavel e adicione-os ao buffer
self.buffered_data += arg.encode("utf-8").hex()
# Absorver todos os blocos que pudermos:
if len(self.buffered_data) * 4 >= self.r:
extra_bits = len(self.buffered_data) * 4 % self.r
# Um ajuste exato!
if extra_bits == 0:
P = self.buffered_data
self.buffered_data = ""
else:
# Fatie-o nos primeiros bits r * a, para alguma constante a> = 1, e o restante total-r * a bits.
P = self.buffered_data[:-extra_bits // 4]
self.buffered_data = self.buffered_data[-extra_bits // 4:]
#Fase de absorcao
for i in xrange((len(P) * 8 // 2) // self.r):
to_convert = P[i * (2 * self.r // 8):(i + 1) * (2 * self.r // 8)] + '00' * (self.c // 8)
P_i = _convertStrToTable(to_convert, self.w, self.b)
# Primeiro aplique o XOR ao estado + bloco
for y in xrange(5):
for x in xrange(5):
self.S[x][y] = self.S[x][y] ^ P_i[x][y]
# Em seguida, aplique a permutacao do bloco, Keccak-F
self.S = Keccak.KeccakF(self.S, self.n_r, self.w)
def digest(self):
"""Retorne o resumo das strings passadas para o metodo update () ate o momento.
Esta eh uma sequencia de bytes digest_size que pode conter dados nao ASCII
caracteres, incluindo bytes nulos."""
if self.last_digest:
return self.last_digest
# AVISO FEIO
# Lidar com conversoes bytestring / hexstring
M = _build_message_pair(self.buffered_data.decode('hex'))
# Primeiro termine o preenchimento e force a atualizacao final:
self.buffered_data = Keccak.pad10star1(M, self.r)
self.update('')
# AVISO FEIO terminado
assert len(self.buffered_data) == 0, "Por que existem dados restantes no buffer? %s com comprimento %d" % (self.buffered_data, len(self.buffered_data) * 4)
# Aperto o tempo!
Z = ''
outputLength = self.n
while outputLength > 0:
string = _convertTableToStr(self.S, self.w)
# Leia os primeiros bits 'r' do estado
Z = Z + string[:self.r * 2 // 8]
outputLength -= self.r
if outputLength > 0:
S = KeccakF(S, verbose)
self.last_digest = Z[:2 * self.n // 8]
return self.last_digest
def hexdigest(self):
"""Como digest(), exceto que o resumo eh retornado como uma sequencia de digitos hexadecimais.
Isso pode ser usado para trocar o valor com seguranca em e-mail ou outros
ambientes nao binarios."""
return self.digest().encode('hex')
def copy(self):
# Inicialize primeiro o que pode ser feito normalmente
duplicate = Keccak(c=self.c, r=self.r, n=self.n)
# Entao copie sobre o estado.
for i in xrange(5):
for j in xrange(5):
duplicate.S[i][j] = self.S[i][j]
# e quaisquer outros dados armazenados
duplicate.buffered_data = self.buffered_data
duplicate.last_digest = self.last_digest
return duplicate
## Funcoes genericas do utilitario
def _build_message_pair(data):
hex_data = data.encode('hex')
size = len(hex_data) * 4
return (size, hex_data)
def _rot(x, shift_amount, length):
"""Gire x shift_amount bits para a esquerda, considerando o \
cadeia de bits tem comprimento bits"""
shift_amount = shift_amount % length
return ((x >> (length - shift_amount)) + (x << shift_amount)) % (1 << length)
### Funcoes de conversao String <-> Tabela (e vice-versa)
def _fromHexStringToLane(string):
"""Converta uma cadeia de bytes gravada em hexadecimal em um valor de faixa"""
#Verifique se a string possui um numero par de caracteres, ou seja, um numero inteiro de bytes
if len(string) % 2 != 0:
raise KeccakError.KeccakError("A cadeia fornecida nao termina com um byte completo")
#Realize a conversao
temp = ''
nrBytes = len(string) // 2
for i in xrange(nrBytes):
offset = (nrBytes - i - 1) * 2
temp += string[offset:offset + 2]
return int(temp, 16)
def _fromLaneToHexString(lane, w):
"""Converta um valor de pista em uma cadeia de bytes gravada em hexadecimal"""
laneHexBE = (("%%0%dX" % (w // 4)) % lane)
#Realize a conversao
temp = ''
nrBytes = len(laneHexBE) // 2
for i in xrange(nrBytes):
offset = (nrBytes - i - 1) * 2
temp += laneHexBE[offset:offset + 2]
return temp.upper()
def _convertStrToTable(string, w, b):
"""Converta uma sequencia de caracteres hexadecimais em sua representacao matricial 5x5
string: sequencia de bytes de bytes codificados em hexadecimal (por exemplo, '9A2C ...')"""
# Verifique se os parametros de entrada sao esperados
if w % 8 != 0:
raise KeccakError("w nao eh multiplo de 8")
# Cada caractere na sequencia representa 4 bits.
# A string deve ter exatamente bits 'b'.
if len(string) * 4 != b:
raise KeccakError.KeccakError("a string nao pode ser dividida em 25 blocos de w bits \
ou seja, a string deve ter exatamente b bits")
#Converter
output = [[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
bits_per_char = 2 * w // 8
for x in xrange(5):
for y in xrange(5):
# Cada entrada tera b / 25 = w bits.
offset = (5 * y + x) * bits_per_char
# Cada entrada tera b / 25 = w bits.
hexstring = string[offset:offset + bits_per_char]
output[x][y] = _fromHexStringToLane(hexstring)
return output
def _convertTableToStr(table, w):
"""Converta uma representacao de matriz 5x5 na sua representacao de cadeia"""
#Verifique o formato de entrada
if w % 8 != 0:
raise KeccakError.KeccakError("w nao eh multiplo de 8")
if (len(table) != 5) or any(len(row) != 5 for row in table):
raise KeccakError.KeccakError("a tabela deve ser 5x5")
#Converter
output = [''] * 25
for x in xrange(5):
for y in xrange(5):
output[5 * y + x] = _fromLaneToHexString(table[x][y], w)
output = ''.join(output).upper()
return output
解决方案
str
已经解码,您正在尝试解码它,它已经解码。但是如果你真的想解码它,你应该编码它,然后再解码它。我不推荐它。
我建议你使用binascii
. 请注意,输入字符串应该是一个类似字节的对象。
import binascii
a = b'hello'
# encoding string to equivalent hex representation
b=binascii.hexlify(a)
print(b)
>>> b'68656c6c6f'
# decoding b
c=binascii.unhexlify(b)
print(c)
>>> b'hello'
推荐阅读
- python - 在 KIvyMD 中除以零
- flutter - 如何在just_audio中扩展后流式传输带有额外信息的mp3文件
- python - 让 CMD 命令在后台运行
- django - i want email has to be unique
- discord.js - 当我尝试创建一个角色时,它给了我一个错误(discord.js)
- java - Spring Cloud Config Server 不适用于 Docker 构建
- servicenow-rest-api - 资产的 ServiceNow 表名
- java - 如果在列表列表中使用 Collections.rotate() 是否对所有元素进行操作?
- java - 如何检查用户定义的对象与 Java 中数组列表的内容是否相等?
- flutter - 尽管 Flutter 中有 SingleChildScrollView,但我无法让我的应用滚动