首页 > 解决方案 > 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

标签: pythonpython-3.xpython-2.x

解决方案


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'

推荐阅读