Java Forum / General / February 2006
Homework
zero - 03 Feb 2006 14:14 GMT After an idea pitched by someone here (I don't remember who, sorry), I've created this template for homework help. Changing the class or method names breaks the code, and so does adding or removing lines above the catch block, making it hard to pass this off as the student's own work. And if they do succeed in changing it enough, I think they deserve to pass ;-) Of course the code specific to the assignment should have some pitfalls too, so they can't just copy and paste into their own class.
Yes, I have too much time on my hands.
import java.lang.reflect.Method; import java.math.BigInteger;
public class DoYourHomeworkYourself { \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u006E\u0061\u006D\u0065\u003D\u0020 \u0022\u0044\u006F\u0059\u0022\u002B \u0022\u006F\u0075\u0072\u0048\u0022 \u002B\u0022\u006F\u006D\u0022\u002B \u0022\u0065\u0077\u006F\u0072\u0022 \u002B\u0022\u006B\u0059\u006F\u0022 \u002B\u0022\u0075\u0072\u0073\u0022 \u002B\u0022\u0065\u006C\u0066\u0022 \u003B\u000A\u000C\u0009\u0020\u0020 \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u006D\u006E\u0061\u006D\u0065\u003D \u0022\u0072\u0075\u006E\u0048\u0022 \u002B\u0022\u006F\u006D\u0065\u0022 \u002B\u0022\u0077\u006F\u0072\u0022 \u002B\u0022\u006B\u0022\u003B\u000C \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u0070\u006E\u0061\u006D\u0065\u003D \u0022\u0072\u0075\u006E\u0022\u003B \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u0072\u006E\u0061\u006D\u0065\u003D \u0022\u007F\u0071\u0052\u0022\u003B static String num = "\u0034\u0039";
public void run() { System.out.println("thanks to comp.lang.java.programmer"); }
public static void main(String args[]) throws Exception { try { Class aClass = Class.forName(name); Object anObject = aClass.newInstance(); Method method1 = aClass.getMethod(mname, (Class[])null); method1.invoke(anObject, (Object[])null); Method method2 = aClass.getMethod(pname, (Class[])null); method2.invoke(anObject, (Object[])null); Method method3 = aClass.getMethod(rname, (Class[])null); method3.invoke(anObject, (Object[])null); } catch(Exception e) { if(e.getStackTrace()[1].getLineNumber() != new BigInteger(num).intValue()) throw new Error("Don't tamper with my code"); } }
public void runHomework() { System.out.println("homework specific code goes here"); } }
tom fredriksen - 03 Feb 2006 14:55 GMT > After an idea pitched by someone here (I don't remember who, sorry), Do you have a description of the idea,
> I've created this template for homework help...
> Yes, I have too much time on my hands. The fact that you coded this is fabulously insane:) thank you, it made my day :))
/tom
> > [quoted text clipped - 62 lines] > } > } zero - 03 Feb 2006 16:33 GMT tom fredriksen <tom@spam-me-not.net> wrote in news:43e36ef7$1 @news.broadpark.no:
>> After an idea pitched by someone here (I don't remember who, sorry), > > Do you have a description of the idea, It was simply to have a class with the name I gave my class, and preventing it from being changed.
>> I've created this template for homework help... > >> Yes, I have too much time on my hands. > > The fact that you coded this is fabulously insane:) thank you, it made > my day :)) glad you liked it :) Feel free to post any ideas you have for improvement.
Alun Harford - 03 Feb 2006 16:17 GMT > After an idea pitched by someone here (I don't remember who, sorry), > I've created this template for homework help. Changing the class or [quoted text clipped - 6 lines] > > Yes, I have too much time on my hands. No, sorry but it won't work yet - too easy to get around, even if you don't know the "secret". Still, with a little work, it could be made harder. More <secret method I'm not going to divulge> is required, particularly around the vulnerable try {} catch {} block. There is also much fun to be had with java.lang.ClassLoader.defineClass(...)
I've set X-No-Archive:Yes on this message. Any other "spoiler" replies should do the same.
Alun Harford
import java.lang.reflect.Method; import java.math.BigInteger;
public class Tampered { \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u006E\u0061\u006D\u0065\u003D\u0020 \u0022\u0044\u006F\u0059\u0022\u002B \u0022\u006F\u0075\u0072\u0048\u0022 \u002B\u0022\u006F\u006D\u0022\u002B \u0022\u0065\u0077\u006F\u0072\u0022 \u002B\u0022\u006B\u0059\u006F\u0022 \u002B\u0022\u0075\u0072\u0073\u0022 \u002B\u0022\u0065\u006C\u0066\u0022 \u003B\u000A\u000C\u0009\u0020\u0020 \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u006D\u006E\u0061\u006D\u0065\u003D \u0022\u0072\u0075\u006E\u0048\u0022 \u002B\u0022\u006F\u006D\u0065\u0022 \u002B\u0022\u0077\u006F\u0072\u0022 \u002B\u0022\u006B\u0022\u003B\u000C \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u0070\u006E\u0061\u006D\u0065\u003D \u0022\u0072\u0075\u006E\u0022\u003B \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006E\u0067 \u0072\u006E\u0061\u006D\u0065\u003D \u0022\u007F\u0071\u0052\u0022\u003B static String num = "\u0034\u0039";
public void run() { System.out.println("thanks to comp.lang.java.programmer"); }
public static void main(String args[]) throws Exception { try { //tamper, tamper, tamper //I can comment out the code below and just invoke runHomework(); Class aClass = Class.forName(name); Object anObject = aClass.newInstance(); Method method1 = aClass.getMethod(mname, (Class[])null); method1.invoke(anObject, (Object[])null); Method method2 = aClass.getMethod(pname, (Class[])null); method2.invoke(anObject, (Object[])null); Method method3 = aClass.getMethod(rname, (Class[])null); method3.invoke(anObject, (Object[])null); } catch(Exception e) { if(e.getStackTrace()[1].getLineNumber() != new BigInteger(num).intValue()) //throw new Error("Don't tamper with my code"); //Above line commented out so can tamper ; //Just needs a semi-colon } }
public void runHomework() { System.out.println("homework specific code goes here"); } }
zero - 03 Feb 2006 16:37 GMT > public static void main(String args[]) throws Exception > { [quoted text clipped - 20 lines] > } > } I moved the reflection into the try block right before posting - before that, any exceptions were just thrown by main, and the linenumber check was done with a throws clause. I thought the trhows clause was too obvious. I shouldn't have moved all the reflection code into the try block though, that does indeed make it easy to circumvent.
When I have the courage to work on it again, I'll try to come up with a better scheme :-)
Stefan Ram - 03 Feb 2006 17:52 GMT >When I have the courage to work on it again, I'll try to come up with a >better scheme :-) People sometimes tell me that the way, I format my source code renders it "unreadable". For example, just several minutes ago, someone on de.comp.lang.java asked how to enumerate all getters of a class using an array and I replied (suppressing the temptation to use reflection):
class TestObject { private final java.lang.String nameGiven = "Hannah"; private final java.lang.String nameSur = "Anderson"; public java.lang.String getNameGiven(){ return this.nameGiven; } public java.lang.String getNameSur(){ return this.nameSur; } @SuppressWarnings("unchecked") private java.util.concurrent.Callable<java.lang.String>[] getters = ( java.util.concurrent.Callable<java.lang.String>[] ) new java.util.concurrent.Callable[] { new java.util.concurrent.Callable<java.lang.String>() { public java.lang.String call(){ return TestObject.this.getNameGiven(); }}, new java.util.concurrent.Callable<java.lang.String>() { public java.lang.String call(){ return TestObject.this.getNameSur(); }}}; public java.util.concurrent.Callable<java.lang.String>[] getGetters(){ return getters; }} public class Main { public static void main( final java.lang.String[] args ) throws java.lang.Exception { final TestObject testObject = new TestObject(); for( java.util.concurrent.Callable<java.lang.String> getter: testObject.getGetters() ) { java.lang.System.out.println( getter.call()) ; }}}
Then another experienced posters said, he was not able to read what I had written, so he will not comment but ignore it.
So maybe my style of formatting is an answer to your problem?
In a sense, I give the one asking a question a hint, but he still will have to invest work decyphering it (like reformatting it in his preferred way).
Oliver Wong - 03 Feb 2006 18:34 GMT >>When I have the courage to work on it again, I'll try to come up with a >>better scheme :-) [quoted text clipped - 39 lines] > still will have to invest work decyphering it (like > reformatting it in his preferred way). Alternatively, he might load it up in Eclipse and press CTRL-F to have it automatically formatted.
I think the ultimate goal here is to find a way to "encrypt" Java source code such that the encrypted version produces identical output to the original program, that the encrypted version will fail whenever any portion of it is modified, and translating from the encrypted version into the unencrypted version is NP-Complete (or possibly not Turing Computable).
- Oliver
Stefan Ram - 04 Feb 2006 02:41 GMT >>private java.util.concurrent.Callable<java.lang.String>[] getters = >>( java.util.concurrent.Callable<java.lang.String>[] ) >>new java.util.concurrent.Callable[] >>{ >Alternatively, he might load it up in Eclipse and press CTRL-F to have >it automatically formatted. This will combine the above 3 lines (plus one character) into a single long line with about 161 characters in Eclipse 3.2:
private java.util.concurrent.Callable<java.lang.String>[] getters = (java.util.concurrent.Callable<java.lang.String>[]) new java.util.concurrent.Callable[] {
Is this now considered to be more readable?
Or compare my line break:
for( java.util.concurrent.Callable<java.lang.String> getter: testObject.getGetters() )
with where Eclipse broke these two lines:
for (java.util.concurrent.Callable<java.lang.String> getter : testObject .getGetters())
Is this a better break point?
Moreover, it was not that simple:
- When I started Eclipse, it complained that it could not find "jdk1.5.0" and it took me some time to find out how to tell Eclipse that I have removed 1.5.0 and that it should use 1.6.0
- Then, when it finally started, Windows froze and I had to reboot and to run Scandisk
This took so much time, that it would have been much faster to reformat by hand.
Moreover, not everybody asking a question would not how to operate Eclipse or a similar formatter.
Oliver Wong - 08 Feb 2006 16:39 GMT >>>private java.util.concurrent.Callable<java.lang.String>[] getters = >>>( java.util.concurrent.Callable<java.lang.String>[] ) [quoted text clipped - 23 lines] > > Is this a better break point? I don't know about these specific examples, but whenever someone posts some Java code on these newsgroups formatted in a way I don't approve of, I just copy and paste the code into Eclipse and use its formatting facility. That, combined with its syntax highlight, mouse over info and code navigation, usually allows me to understand what the code is doing pretty quickly. I sometimes also use the refactoring facilities to rename the variables and methods to something more meaningful to me.
> Moreover, it was not that simple: > [quoted text clipped - 11 lines] > Moreover, not everybody asking a question would not > how to operate Eclipse or a similar formatter. I was thinking of the "worst case" of someone who is infinitely smart, but wants to do the minimal amount of work to get a homework assignment done. It's basically a form of the "adversarial" argument. We're trying to come up with ways of formatting Java Code so that they could not be used in homework without making it obvious to the teacher that the code was plagiarised. But every technique we've come up with so far could be machine translated into a form where the plagiarism isn't so obvious.
- Oliver
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|