Я думаю, у меня получилось. Я нашел оригинальный код на github , который помог мне создать контрольный пример. Посмотрев на проблемы, я последовал решению, которое вы придумали, и расшифровал байты в iso-8859-1
вместо utf-8
, и это сработало.
from struct import Struct
from base64 import b64decode
import hashlib
import hmac
from operator import xor
from itertools import starmap
_pack_int = Struct('>I').pack
def check_hash(password, hash_):
"""Check a password against an existing hash."""
if isinstance(password, str):
password = password.encode('utf-8')
algorithm, hash_function, cost_factor, salt, hash_a = hash_.split(' Вместо того, чтобы продолжать настраивать этот скрипт и поддерживать его, я бы посоветовал взглянуть на реализации этой же функции в python3.
Ссылки
)
assert algorithm == 'PBKDF2'
hash_a = b64decode(hash_a).decode('iso-8859-1')
hash_b = pbkdf2_bin(password, salt, int(cost_factor), len(hash_a),
getattr(hashlib, hash_function))
assert len(hash_a) == len(hash_b) # we requested this from pbkdf2_bin()
# Same as "return hash_a == hash_b" but takes a constant time.
# See http://carlos.bueno.org/2011/10/timing.html
diff = 0
for char_a, char_b in zip(hash_a, hash_b):
diff |= ord(char_a) ^ ord(char_b)
return diff == 0
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac):
h = mac.copy()
h.update(x)
return list(map(ord, h.digest().decode('iso-8859-1')))
buf = []
for block in range(1, -(-keylen // mac.digest_size) + 1):
myx = salt.encode('utf-8') + _pack_int(block)
rv = u = _pseudorandom(myx)
for i in range(iterations - 1):
u = _pseudorandom(''.join(map(chr, u)).encode('iso-8859-1'))
rv = starmap(xor, zip(rv, u))
buf.extend(rv)
return ''.join(map(chr, buf))[:keylen]
if __name__ == "__main__":
print(check_hash('Xs12\'io!12', 'PBKDF2$sha256$10000$r+Gy8ewTkE7Qv0V7$uqmgaPgpaT1RSvFPMcGb6cGaFAhjyxE9'))
Вместо того, чтобы продолжать настраивать этот скрипт и поддерживать его, я бы посоветовал взглянуть на реализации этой же функции в python3.
Ссылки
То, о чем говорит Ваш коллега, не является DAL большей частью счета народов. DAL должен инкапсулировать любые вызовы к базе данных, сохранил ли сделанный динамическим SQL, procs или ORM с чем-то как IRepository. Ваши веб-страницы никогда не должны содержать SQL или бизнес-логику, или иначе это становится кошмаром обслуживания.
Очень простой пример для.NET был бы следующие.
Если имеют два класса: SomePage (который является Страницей ASP.NET) и DataService (который является простым классом C#),
Если SomePage всегда звонит в DataService к данным чтения-записи затем, у Вас есть Уровень доступа к данным. SomePage не будет содержать SQL или ссылок на Систему. Данные. Классы SqlClient.
Но SomePage может использовать DataSets или бизнес-объекты, которые передаются от и до класса DataService.
"Черный квадрат", который содержит Ваши данные. Если это - пользователь, заботится/может, говорят, что существует DB назад там (кроме на соображение), это не совсем, о чем я думаю
В дополнение к тому, что другие сказали, я обычно считаю это местом к краткому обзору, как Ваши данные хранятся. Действительно хороший уровень доступа к данным должен позволить Вам выгружать Oracle, SQL Server, Доступ, плоский текстовый файл, XML, или независимо от того, что Вы хотите, и выполнение так было бы очевидно для других прикладных уровней. Другими словами, контракт между уровнем доступа к данным и другими слоями должен быть определен в агностике базы данных путь.
Я лично определяю DAL как, где взаимодействия между моим приложением и базой данных существуют. Таким образом, у меня может быть Бизнес-Слой, который взаимодействует с DAL для разрешения операций CRUD.
EG у меня может быть ModelClass. LoadAll () метод, который взаимодействовал бы с DAL, который выберет данные и ModelClass, использовал бы те данные любым способом, которым этому было нужно.
Я предпочитаю сохранять DAL максимально легким, но некоторые другие люди предпочитают другой путь, где заполнение Данных модели происходит в DAL.
Данные доступов уровня доступа к данным и ничто иное.