Hoe kan ik de tijger-hash-waarden van de officiële implementaties omzetten in het formulier dat door Direct Connect wordt gebruikt?

Ik probeer een Direct Connect -client te implementeren en ik zit momenteel vast aan een punt waar ik de bestanden moet hashen om ze naar andere klanten te kunnen uploaden.

Omdat alle andere clients een TTHL ( Tiger Tree Hashing Leaves) ondersteuning vereisen voor verificatie van de gedownloade gegevens. Ik heb naar implementaties van het algoritme gezocht en heb tiger-hash-python gevonden.

Ik heb een routine geïmplementeerd die de hash-functie van voordien gebruikt en kan grote bestanden hashen, volgens de logica die is opgegeven in Tree Hash EXchange-indeling (THEX) (in feite is het boomdiagram het belangrijkste deel op die pagina).

De waarde die wordt geproduceerd, is echter vergelijkbaar met die weergegeven op Wikipedia , een hex-digest, maar verschilt van die in de DC-clients die ik gebruik ter referentie.

Ik heb niet kunnen achterhalen hoe de hex-digest-vorm is omgezet naar deze andere (39 tekens, A-Z, 0-9). Kan iemand uitleggen hoe dat is gebeurd?


Nou ... ik probeerde wat Paulo Ebermann zei, met behulp van de volgende functies:

def strdivide(list,length):
    result = []
    # Calculate how many blocks there are, using the condition: i*length = len(list).
    # The additional maths operations are to deal with the last block which might have a smaller size
    for i in range(0,int(math.ceil(float(len(list))/length))):
        result.append(list[i*length:(i+1)*length])
    return result
def dchash(data):
    result = tiger.hash(data) # From the aformentioned tiger-hash-python script, 48-char hex digest
    result = "".join([ "".join(strdivide(result[i:i+16],2)[::-1]) for i in range(0,48,16) ]) # Representation Transform
    bits = "".join([chr(int(c,16)) for c in strdivide(result,2)]) # Converting every 2 hex characters into 1 normal
    result = base64.b32encode(bits) # Result will be 40 characters
    return result[:-1] # Leaving behind the trailing '='

De TTH voor een leeg bestand bleek 8B630E030AD09E5D0E90FB246A3A75DBB6256C3EE7B8635A te zijn, die na de transformatie hier , wordt 5D9ED00A030E638BDB753A6A24FB900E5A63B8E73E6C25B6 . Base-32 codering van dit resultaat leverde LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ op, wat bleek te zijn wat DC ++ genereert.

3
Ik denk dat een TTH meestal base32 is en niet base16/hex-gecodeerd.
toegevoegd de auteur CodesInChaos, de bron

1 antwoord

De enige vermelding van het formaat van de hash in het Direct Connect-protocol dat ik vond, is op de $ SR-pagina op de NMDC-protocolwiki :

For files containing TTH, the parameter is replaced with TTH: (ref: TTH_Hash).

Het is dus Base32-codering. Dit wordt gedefinieerd in RFC 4648 (en enkele eerdere), sectie 6 . Kortom, u gebruikt de hoofdletters A-Z en de decimale cijfers 2 tot en met 7, en één base32-cijfer vertegenwoordigt 5 bits, terwijl één base16 (hexadecimaal) cijfer slechts 4 enen vertegenwoordigt.

Dit betekent dat elke 5 hexadecimale kaart is toegewezen aan 4 base32-cijfers en voor een Tiger-hash (192 bits) heb je 40 base32-cijfers nodig (in de officiële codering zou de laatste een = zijn opvulling, wat lijkt te worden weggelaten als je zegt dat er altijd 39 tekens zijn).

Ik ben niet zeker van een implementatie van een conversie van hex (of bytes) naar base32, maar het moet niet te ingewikkeld zijn met een opzoektabel en wat bit-shifting.

2
toegevoegd
Bedankt ... dat was erg nuttig.
toegevoegd de auteur Kaustubh Karkare, de bron