Bonjour à vous, j'aimerai traduire un code écrit en python vers le langage Java. Seul problème, j'ai un peu de mal à lire du python. Quelqu'un pourrait-il me commencer chaque ligne de ce que fait le code ci-dessous ? ainsi que le type des valeurs en entrée/sortie des fonctions. J'ai souvent du mal avec le sucre syntaxe de python.
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Util import Counter
import base64
import binascii
import json
import os
import random
import struct
import sys
import urllib
sid = ''
seqno = random.randint(0, 0xFFFFFFFF)
master_key = ''
rsa_priv_key = ''
def base64urldecode(data):
data += '=='[(2 - len(data) * 3) % 4:]
for search, replace in (('-', '+'), ('_', '/'), (',', '')):
data = data.replace(search, replace)
return base64.b64decode(data)
def base64urlencode(data):
data = base64.b64encode(data)
for search, replace in (('+', '-'), ('/', '_'), ('=', '')):
data = data.replace(search, replace)
return data
def a32_to_str(a):
return struct.pack('>%dI' % len(a), *a)
def a32_to_base64(a):
return base64urlencode(a32_to_str(a))
def str_to_a32(b):
if len(b) % 4: # Add padding, we need a string with a length multiple of 4
b += '\0' * (4 - len(b) % 4)
return struct.unpack('>%dI' % (len(b) / 4), b)
def base64_to_a32(s):
return str_to_a32(base64urldecode(s))
def aes_cbc_encrypt(data, key):
encryptor = AES.new(key, AES.MODE_CBC, '\0' * 16)
return encryptor.encrypt(data)
def aes_cbc_decrypt(data, key):
decryptor = AES.new(key, AES.MODE_CBC, '\0' * 16)
return decryptor.decrypt(data)
def aes_cbc_encrypt_a32(data, key):
return str_to_a32(aes_cbc_encrypt(a32_to_str(data), a32_to_str(key)))
def aes_cbc_decrypt_a32(data, key):
return str_to_a32(aes_cbc_decrypt(a32_to_str(data), a32_to_str(key)))
def stringhash(s, aeskey):
s32 = str_to_a32(s)
h32 = [0, 0, 0, 0]
for i in xrange(len(s32)):
h32[i % 4] ^= s32[i]
for _ in xrange(0x4000):
h32 = aes_cbc_encrypt_a32(h32, aeskey)
return a32_to_base64((h32[0], h32[2]))
def prepare_key(a):
pkey = [0x93C467E3, 0x7DB0C7A4, 0xD1BE3F81, 0x0152CB56]
for _ in xrange(0x10000):
for j in xrange(0, len(a), 4):
key = [0, 0, 0, 0]
for i in xrange(4):
if i + j < len(a):
key[i] = a[i + j]
pkey = aes_cbc_encrypt_a32(pkey, key)
return pkey
def encrypt_key(a, key):
return sum((aes_cbc_encrypt_a32(a[i:i+4], key) for i in xrange(0, len(a), 4)), ())
def decrypt_key(a, key):
return sum((aes_cbc_decrypt_a32(a[i:i+4], key) for i in xrange(0, len(a), 4)), ())
def mpi2int(s):
return int(binascii.hexlify(s[2:]), 16)
def get_chunks(size):
chunks = {}
p = pp = 0
i = 1
while i <= 8 and p < size - i * 0x20000:
chunks[p] = i * 0x20000;
pp = p
p += chunks[p]
i += 1
while p < size:
chunks[p] = 0x100000;
pp = p
p += chunks[p]
chunks[pp] = size - pp
if not chunks[pp]:
del chunks[pp]
return chunks
#Je ne vais pas détailer les modules, on verra au moment voulu
#ceux là sont d'un package externe (PyCrypto)
from Crypto.Cipher import AES
from Crypto.PublicKey import RSA
from Crypto.Util import Counter
#ceux là de la lib standard
import base64
import binascii
import json
import os
import random
import struct
import sys
import urllib
sid = '' # initialise une chaine de caractere vide, mais tu t'en doute, non ?
seqno = random.randint(0, 0xFFFFFFFF) # tire un nombre entier aléatoire entre 0 et 0xFFFFFFFF (les deux compris : 0 <= seqno <= 0xFFFFFFFF)
# bon je suppose que tu sais que 0xFFFFFFFF est un nombre en notation hexa... Mais je fais peut etre beaucoup de supposition là
master_key = '' # idem sid
rsa_priv_key = '' # idem sid
def base64urldecode(data):
# a priori data est une string(une url encodé en base64 je dirais même )
# Un peu bizarre la ligne suivante...
# En gros rajoute :
# * "==" à la fin de la chaine pour toutes les chaine dont la longueur est de la forme 4*N+2 (Chaine de longueur 2, 6, 10, ...)
# * "=" à la fin de la chaine pour toutes les chaine dont la longueur est de la forme 4*N+3 (Chaine de longueur 3, 7, 11, ...)
# * ne rajoute rien sinon...
# Etrange car j'ai du mal à voir la logique mais c'est pas vraiment mon prob...
data += '=='[(2 - len(data) * 3) % 4:]
# Les 2 lignes suivantes remplacent dans data :
# Les «-» par des «+», les «_» par des «/» et supprime les «,»
for search, replace in (('-', '+'), ('_', '/'), (',', '')):
data = data.replace(search, replace)
#decode et retourne 'data' considéré encodé en base64 ( RFC 3548 ) (une chaine de caractère donc)
return base64.b64decode(data)
def base64urlencode(data):
# a priori data est une string (une url je dirais même )
# encode 'data' en base64 ( RFC 3548 )
data = base64.b64encode(data)
# Les 2 lignes suivantes remplacent dans data :
# Les «+» par des «-», les «/» par des «_» et supprime les «=»
for search, replace in (('+', '-'), ('/', '_'), ('=', '')):
data = data.replace(search, replace)
# et on retourne la chaine
return data # (une chaine de caractère donc)
def a32_to_str(a):
# a est une liste d'entiers
# convertis tous les entiers en une longue chaine de caractères.
# Chaque entier dans la liste est considéré comme un "unsigned int" de 32bits et est convertis en 4 caractères.
# Tous les groupes de 4 caractères sont concaténés
return struct.pack('>%dI' % len(a), *a)
def a32_to_base64(a):
# pas besoin de décrire ça, donc ? avec les fonctions precedentes
return base64urlencode(a32_to_str(a))
def str_to_a32(b):
# Les lignes suivantes rajoutent des caractères nuls ('\0') à la fin pour que la chaine soit une chaine de longueur multiple de 4
if len(b) % 4: # Add padding, we need a string with a length multiple of 4
b += '\0' * (4 - len(b) % 4)
# fait l'inverse de a32_to_str(). Chaque groupe de 4 caractères sont regroupés pour formés un mot de 32 bits interprété comme un unsigned int.
# On obtient donc une liste d'entiers, chaque entier etant le decodage de 4 caracteres
return struct.unpack('>%dI' % (len(b) / 4), b)
def base64_to_a32(s):
# pas besoin de décrire ça, donc ? avec les fonctions precedentes
return str_to_a32(base64urldecode(s))
def aes_cbc_encrypt(data, key):
# data est une chaine de caracteres à encoder, key la clé (chaine aussi). Depuis la doc :
# The secret key to use in the symmetric cipher. It must be 16 (AES-128), 24 (AES-192), or 32 (AES-256) bytes long.
# le mode CBC :
# Cipher-Block Chaining (CBC). Each of the ciphertext blocks depends on the current and all previous plaintext blocks. An Initialization Vector (IV) is required.
# The IV is a data block to be transmitted to the receiver. The IV can be made public, but it must be authenticated by the receiver and it should be picked randomly.
# See NIST SP800-38A , Section 6.2 .
# Je n'y connait pas grand chose en codage donc je te laisse interpreter ce "cryptage"
encryptor = AES.new(key, AES.MODE_CBC, '\0' * 16)
return encryptor.encrypt(data)
def aes_cbc_decrypt(data, key):
# Fait l'inverse de la fonction precedente
decryptor = AES.new(key, AES.MODE_CBC, '\0' * 16)
return decryptor.decrypt(data)
def aes_cbc_encrypt_a32(data, key):
# pareil que aes_cbc_encrypt mais les paremetres et le retour sont des suites d'entiers
return str_to_a32(aes_cbc_encrypt(a32_to_str(data), a32_to_str(key)))
def aes_cbc_decrypt_a32(data, key):
# pareil que aes_cbc_decrypt mais les paremetres et le retour sont des suites d'entiers
return str_to_a32(aes_cbc_decrypt(a32_to_str(data), a32_to_str(key)))
def stringhash(s, aeskey):
# Converti la chaine s en liste d'entiers
s32 = str_to_a32(s)
#initialisation...
h32 = [0, 0, 0, 0]
# Pour i allant de 0 à la taille de s32...
for i in xrange(len(s32)):
# ... L'élément (i modulo 4) de h32 est le XOR de sa valeur precedente avec l'entier numero i de s32
h32[i % 4] ^= s32[i]
# applique 16384 fois consécutivement un aes_cbc_encrypt_a32 depuis h32 avec la clé passé en paramètre
for _ in xrange(0x4000):
h32 = aes_cbc_encrypt_a32(h32, aeskey)
# Renvois une chaine de 8 caractères à partir du decodage des entiers d'index 0 et 2 de h32
return a32_to_base64((h32[0], h32[2]))
def prepare_key(a):
# a doit etre une liste d'entiers
#initialisation...
pkey = [0x93C467E3, 0x7DB0C7A4, 0xD1BE3F81, 0x0152CB56]
# On applique 65536 fois la meme boucle
for _ in xrange(0x10000):
# Tous les 4 entiers...
for j in xrange(0, len(a), 4):
# On mets les 4 entiers dans "key"
key = [0, 0, 0, 0]
for i in xrange(4):
if i + j < len(a):
key[i] = a[i + j]
# On encode "pkey" avec la "key" de 4 entiers formé juste avant qui devient la nouvelle "pkey"
pkey = aes_cbc_encrypt_a32(pkey, key)
return pkey
def encrypt_key(a, key):
# forme une liste concaténation de toutes les listes d'entiers renvoyé par aes_cbc_encrypt_a32 appliqué par paquet de 4 caractères
return sum((aes_cbc_encrypt_a32(a[i:i+4], key) for i in xrange(0, len(a), 4)), ())
def decrypt_key(a, key):
# pareil que precedement, mais en appel avec aes_cbc_decrypt_a32
return sum((aes_cbc_decrypt_a32(a[i:i+4], key) for i in xrange(0, len(a), 4)), ())
def mpi2int(s):
# s est une chaine de caractere
# binascii.hexlify() va convertir tous les caractères, à partir du 2eme, un à un et les concaténer.
# Chaque conversion converti le caractère courant vers le nombre ascii correspondant sous forme de char.
# Donc '0' devient '30', '1' devient '31',... 'A' devient '41', 'm' devient '6D'
# Donc binascii.hexlify(s[2:]) avec une chaine de la forme "??01Am" va devenir la chaine '3031416D'. (je te rappel que les 2 premiers caractères sont ignorés)
# Enfin la chaine de caractere est interprété comme un nombre hexa et est converti en entier
return int(binascii.hexlify(s[2:]), 16)
def get_chunks(size): # size est un entier
chunks = {} # chunks est un dictionnaire (a priori association entre un entier et un autre entier)
p = pp = 0
i = 1
# Tu devrait le comprendre seul ces boucles, non ?
while i <= 8 and p < size - i * 0x20000:
chunks[p] = i * 0x20000;
pp = p
p += chunks[p]
i += 1
while p < size:
chunks[p] = 0x100000;
pp = p
p += chunks[p]
chunks[pp] = size - pp
# Si chunks[pp] est nul, on le supprime du dico
if not chunks[pp]:
del chunks[pp]
return chunks
oui c'est ce qui me faisait réagir. Pour moi Jython n'est qu'une reprise du Python sur la JVM, il utilise la syntaxe mais quoi d'autres ? Peut etre une partie de la lib standard (et encore?) mais je doute fortement qu'il soit compatible avec les modules externes natifs
Il me semble (ça fait longtemps que j'ai pas consulté la mailing list) que la communauté fait un gros effort pour porter la majorité des modules de la bibliothèque standard en pur Python, quitte à proposer des alternatives en natif pour CPython (genre ElementTree vs. cElementTree), de façon à ne pas mettre trop de bâtons dans les roues à Pypy et Jython.
Je vois aussi Jython comme un compilo Python vers du bytecode Java.
Pour les bibliothèques externes en natif, je pense aussi que c'est mort.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.