2 votes

Rendre une source Java inexploitable mais toujours lisible par l'homme

Je voudrais donner mes sources Java à un autre développeur Java afin qu'il puisse les étudier alors qu'il ne devrait pas pouvoir les compiler. Je cherche un algorithme simple mais efficace pour rendre mes sources non compilables. J'espère avoir expliqué clairement l'objectif.

Ma première idée était de parcourir toutes mes sources et de mélanger aléatoirement la casse de tous mes noms de méthodes :

private double getAvailableCash() --> private double gEtaVailabLEcASh()

C'est assez simple et pas si facile à refaire, bien que ce ne soit pas impossible. Pouvez-vous me suggérer d'autres façons, de préférence meilleures?

Mise à jour:

Beaucoup d'entre vous ont commenté/demandé la raison pour laquelle quelqu'un voudrait faire cela. Supposons le scénario suivant : vous devez prouver que vous êtes prêt avec une solution de bonne qualité avant que l'autre développeur ne vous paie, mais vous ne lui faites pas confiance pour une bonne raison. Montrer une démo compilée fonctionnelle ne suffit pas car il veut voir la façon dont vous avez travaillé. Si vous lui donniez le code source compilable, il est possible que vous ne receviez pas votre paiement aussi rapidement que si vous ne lui donniez pas le code source.

Quoi qu'il en soit, cela m'a semblé être un problème très intéressant et amusant et j'ai vu de nombreux commentaires et réponses, même pour beaucoup d'entre vous.. :-)

6voto

fge Points 40850

Je ne sais pas pourquoi vous voudriez faire ça mais bon...

perl -pi -e 'undef $/; s,^,\00,' $(find -name "*.java")

Vous n'aurez même pas à changer le code!

Cela ajoute un octet unique, qui est 0, au début de chaque fichier nommé *.java. Et oui, cela suffit à rendre un fichier non compilable!

Pour annuler :

perl -pi -e 's,^\00,,' $(find -name "*.java")

Un peu plus d'explication sur $/ : c'est le séparateur d'entrée que perl utilise pour lire à partir de flux. Il est défini par défaut sur un retour à la ligne, c'est pourquoi normalement perl lit ligne par ligne. Ici il est défini sur rien, ce qui signifie qu'il lit le fichier entier d'un coup. S'il est défini sur une chaîne vide, il lira paragraphe par paragraphe. Et vous pouvez le définir sur ce que vous voulez.

4voto

Jon Skeet Points 692016

Si elles sont lisibles, alors il ne serait probablement pas difficile de les rendre compilables aussi. De plus, le changement de cas rend difficile la compréhension, mais reste un code parfaitement valide.

Étant donné que la valeur de voir l'algorithme, etc. est plutôt plus importante que la valeur de la traduction de cet algorithme en code, il n'est pas vraiment clair pourquoi vous ne donnez pas tout simplement le code source original au développeur.

2voto

Dave Newton Points 93112

Traduisez en quelque chose d'autre que Java, comme du pseudo-code. Tout ce qui est lisible sera compilable. Même si ce n'était pas le cas, votre algorithme serait directement (plus ou moins) transposable en Java de toute façon.

Votre seule bonne solution est un accord légalement contraignant. Si vous ne leur faites pas confiance, envisagez de ne pas faire affaire avec eux en premier lieu.

Le mieux que vous pourriez faire serait de supprimer des choses comme les accolades (et autres signes de ponctuation) et de désindenter; cela le rendrait non compilable, il ne serait pas toujours évident où ils devraient être remis, etc. Supprimez les informations de package et d'import. Supprimez les informations d'accès et de type. Supprimez les getters et les setters. Supprimez les blocs try/catch. Supprimez les commentaires.

Cela vous laisserait avec quelque chose comme ceci :

Étudiant

nom;
adresse;

Étudiant(nom)
    this.nom = nom

nom_utilisateur = ""
mot_de_passe = ""

vérifierUtilisateur(conn)
    résultat = null
    stmt = null

    stmt = conn.prepareStatement("SELECT * FROM tutor WHERE uid=?")
    stmt.setString(0, nom_utilisateur)
    résultat = stmt.executeQuery()
    while (résultat.next())
    psw1 = résultat.getString("psw1")
    if (mot_de_passe.equals(psw1))
    return "succès"
    e.printStackTrace()
    fermer(conn, stmt, résultat)

    return "erreur"

getConnection()
    Class.forName("com.informix.jdbc.IfxDriver")
    conURL = "jdbc:informix-sqli://*********/fxg:INFORMIXSERVER=sgdbuat11;user=*****;password=******"
    return DriverManager.getConnection(conURL)
    e.printStackTrace()
    return null

close(conn, stmt, result)
    if (résultat != null) résultat.close()
    if (stmt != null)   stmt.close()
    if (conn != null)   conn.close()
    e.printStackTrace()

2voto

yshavit Points 15028

Et si on supprimait simplement tous les points-virgules et les accolades ? Vous risquez de perturber une chaîne de caractères ici ou là, mais c'est probablement bien pour ce que vous essayez de faire.

Alternativement, vous pourriez écrire un décompileur bytecode dont la cible est LOLCODE

1voto

Óscar López Points 97105

Que diriez-vous de supprimer toutes les imports et les déclarations de package de vos fichiers sources ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X