2

I'd like to give my Java sources to another Java developer so that he can study them while he should be unable to compile them. I am looking for a simple but effective one-way algorithm making my sources uncompilable. I hope I explained the goal clearly.

My first idea was parsing all my sources and making all my method names random mixed case:

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

It is quite simple and not so easy to redo, not impossible though. Can you suggest me some other, hopefully better ways?

Update:

Many of you commented/asked about the reason that someone would like to do this. Suppose the following scenario: you have to prove that you are ready with a good quality solution before the other developer pays you, but you do not trust him for a good reason. Showing a working compiled demo is not enough because he wants to see the way you worked. If you gave him the compilable source it is possible that you would not get your payment as soon as you would without giving the source..

Anyway, it seemed a very interesting, funny problem to me and seeing the many comments and answers even for many of you.. :-)

8
  • 2
    Why is this something you would want to do? Commented Dec 17, 2011 at 18:06
  • 1
    Just leave out some classes neededfor it to be useful. Exactly like the src.zip with the JDK. Commented Dec 17, 2011 at 18:06
  • 1
    Wait, if he can't compile them, he won't be able to "study" them for anything useful, it'd be pointless don't you think? Commented Dec 17, 2011 at 18:08
  • @ÓscarLópez see my solution... No need to make them unreadable at all, no need to even change one line of code. This simple one-liner doesn't change the code at all, files can be opened in an editor but they are not compilable! Commented Dec 17, 2011 at 18:16
  • Why wouldn't you want the other developer to compile it? Do you have trust issues? Commented Dec 17, 2011 at 18:21

8 Answers 8

6

I don't know why you would want to do this but anyway...

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

You will not even have to change code!

What this does is add a single byte, which is 0, to the beginning of each file named *.java. And yes, this is enough to make a file not able to compile!

To undo:

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

A little more explanation about $/: it is the input separator which perl uses to read from streams. It is set to a newline by default, which is why normally perl reads line by line. Here it is defined to nothing, which means it reads the whole file at once. If it is defined to an empty string, it will read paragraph by paragraph. And you can define it to anything you like.

Sign up to request clarification or add additional context in comments.

2 Comments

For those of us who can't read Perl, can you add a description of what this does?
I like the irony of getting uncompilable-but-readable Java using unreadable-but-compilable perl.
4

If they're readable, then presumably it wouldn't be hard to make it compilable too. Besides, changing the case makes it hard to understand, but still perfectly valid code.

Given that the value of seeing the algorithm etc is rather more than the value of the translation of that algorithm into code, it's not really clear why you don't just give the developer the original source code.

2 Comments

I did not downvote. However changing the case (if inconsistent) would make it uncompilable without reducing readabilty too much. Consider: class MyClass { static void doStuff ( ) { } public static void String [ ] args ) { dostuff ( ) ; } } I still agree with your point about giving the developer the original source code.
@emory: But it would only make it temporarily uncompilable - it would be reasonably simple to fix it up to make it compile. The increase in difficulty to get it compiling isn't as great as the increase in difficulty to understand, IMO - making it counterproductive.
2

How about just deleting all semicolons and curly braces? You may mess up a string literal here or there, but that's likely to be fine for whatever you're trying to do.

Alternatively, you could write a bytecode decompiler whose target is LOLCODE

1 Comment

Very good. Changing braces to something random similar looking charseq is cool
2

Translate to something other than Java, like pseudo-code. Anything readable will be compilable. Even if it wasn't, your algorithm would be directly (more or less) translatable into Java anyway.

Your only good solution is a legally-binding agreement. If you don't trust them, consider not doing business with them in the first place.

Best you could do might be to strip out things like curly-braces (and other punctuation) and de-indent; that would make it uncompilable, it wouldn't always be obvious where they should be put back in, etc. Remove package and import info. Remove access info and type info. Remove getters and setters. Remove try/catch blocks. Remove comments.

This would leave you with something like this:

Student

name;
address;

Student(name)
    this.name = name

username = ""
password = ""

checkUser(conn)
    result = null
    stmt = null

    stmt = conn.prepareStatement("SELECT * FROM tutor WHERE uid=?")
    stmt.setString(0, username)
    result = stmt.executeQuery()
    while (result.next())
    String psw1 = result.getString("psw1")
    if (password.equals(psw1))
    return "success"
    e.printStackTrace()
    close(conn, stmt, result)

    return "error"

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 (result != null) result.close()
    if (stmt != null)   stmt.close()
    if (conn != null)   conn.close()
    e.printStackTrace()

2 Comments

Consider huge amount of already made Java source. I would prefer something automatic..
@jabal You're asking for something essentially impossible, or at best, useless. See updated answer for some more ideas, which could be automated to a great degree without an AST, completely with one.
1

How about deleting all the imports and package declarations from your source files?

Comments

1

Create a PDF file from the source code. And disable copying of the pdf document content. Maybe you should also disable printing of the document.

2 Comments

Well just be aware that pdf owner passwords are about the most useless "security" device ever invented - well we're talking about Adobe here so no wonder.
Good idea, however I prefer the ideas changing the source files somehow. Thanks anyway!
1

Use JavaDocs. It will print a nice human-readable description of your code that will not compile.

Comments

1

Make the source code a captcha. You know, print characters with different colors or textures, different fonts, some distortion, some rotation, add random lines, noise, blurring, etc.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.