-1

There's this problem in Codewars https://www.codewars.com/kata/58a3fa665973c2a6e80000c4/train/java

We will have to just square root a very big number. Of course all of us would think about BigInteger.sqrt - but the challenge itself reject these words: reflection, biginteger, bigdecimal, runtime, process, script. (P/s you can't use unicode either).

Update: also blocked "newInstance", "invoke"

Well there's no fun in doing what intended for the task, so I currently trying to bypass this by using bytebuddy (luckily they don't reject this).

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.dynamic.DynamicType.Loaded;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.matcher.ElementMatchers;

public class Kata { 
  public static String integerSquareRoot(String n) {
    ByteBuddyAgent.install();
        Loaded<Kata> dynamicType = new ByteBuddy().redefine(Kata.class).method(ElementMatchers.named("text"))
                .intercept(FixedValue.value(new java.math.BigInteger(n).sqrt().toString())).make()
                .load(Thread.currentThread().getContextClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
    return Kata.text("forsenCD");
    }
  
  public static String text(String n){
    return n;
  }
}

What it does here is to force the text() method to return what's in the intercept

This solution itself solve the task, but as you can see, it still have "BigInteger" in the intercept.

I'm noob at bytebuddy, so anyone have a way to solve this using bytebuddy reflection, that maybe can change the BigInteger in the intercept with a string (so I can use character array) to solve this.

Or maybe even using Nashorn engine to get to some JavaScript API.

Please feel free to share your thought.

Luka
  • 55
  • 1
  • 7
  • Sorry to crash your party, but is the purpose of Codewars to learn programming or to find ways to hack the kata's preconditions? To me this sounds pretty clear: _"To make this kata worth its rank, **some APIs are not allowed** in your Java solution."_ So stop being lazy and implement the solution by yourself. It is a coding kata, for heaven's sake! – kriegaex Jul 28 '23 at 00:31
  • well I actually learning ByteBuddy from Codewars task. But I guess you are in the right. Like I said, it's boring to do the right way, and this way is not actually "lazy", will need an extensive amount of reflection knowledge to pull through this – Luka Jul 28 '23 at 02:43
  • 1
    I think there are better ways to learn BB. But of course, you choose your own path while trying to learn something new. Good luck with that. As for this particular kata, I still think it makes sense to not trick your way around it but solve it. It might prove to be quite challenging and not so boring, after all. – kriegaex Jul 28 '23 at 03:12

1 Answers1

1

Sure, since we're hacking anyway, this should be fun:

  1. Instead of calling the BigInteger constructor directly, call it using reflection: Class.forName("java.math.BigInteger").newInstance(n) *
  2. Now take that String literal, and apply an encoding of your choice. Base64 should do. Save the encoded string as a constant.
  3. At runtime, decode the String and pass it to Class.forName.

* Does newInstance have a varargs option? If not, use getConstructors instead and call the right one.

Jorn
  • 20,612
  • 18
  • 79
  • 126
  • Or, you could just hardcode a `char[]` and pass that to a `String` constructor. Should work depending on how exactly they check the code. – Jorn Jul 27 '23 at 11:14
  • Regex on the input file. – Johannes Kuhn Jul 27 '23 at 12:30
  • I followed your way and was able to solve this, but they also blocked "newInstance" and "invoke" keyword though. That's why I have to use ByteBuddy for more options – Luka Jul 27 '23 at 13:29
  • Do you think that BB does not use the same calls that are forbidden in this kata? It simply wraps them. You could just as easily build your own wrapper library, consisting of a single class, and just call that class to circumvent the source code check. But that is not a solution, just a cheap cheat. Besides, are you sure you can just call any external libraries from a coding kata like that? In that case, those katas would not be a challenge at all. As far as I can see, ByteBuddy is not allowed there: https://docs.codewars.com/languages/java only lists JUnit and a few other libraries. – kriegaex Jul 30 '23 at 02:19