blob: 2fb848b2f4d8e473f24142fe8f43c3777b5adccf [file] [log] [blame]
---
layout: post
status: PUBLISHED
published: true
title: Fun with obfuscated Groovy
author:
display_name: Paul King
login: paulk
email: paulk@apache.org
author_login: paulk
author_email: paulk@apache.org
id: 5ad9bae4-2b86-4964-82e8-c2e93349ea16
date: '2022-12-08 00:40:23 -0500'
categories:
- Technology
tags:
- groovy
comments: []
permalink: groovy/entry/fun-with-obfuscated-groovy
---
<p>An interesting tweet appeared in my feed this morning:</p>
<p><img style="width:80%" src="https://blogs.apache.org/groovy/mediaresource/e3a9547d-2715-4f93-96eb-f5a7ad75fb85" alt="ObfuscatedJava@joshbloch.png"></p>
<p><br></p>
<p>And of course it prints the same thing in Groovy:</p>
<pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono',monospace;font-size:9.6pt;"><span style="color:#cc7832;">char </span>p(<span style="color:#cc7832;">int </span>i) {<br> (<span style="color:#cc7832;">char</span>) (<span style="color:#6897bb;">72.5<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">17488.589319014318<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">54923.96120078333<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">72666.96791801952<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">54398.97479321991<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">25980.955221285272<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">8426.37914599868<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">1921.5090334614745<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">313.59919165032926<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">36.799215753141524<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">3.0787816564704586<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">0.17913536718875267<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">0.0068850803421115925<br></span><span style="color:#6897bb;"> </span>+ i * (<span style="color:#6897bb;">1.5709912194287188E-4<br></span><span style="color:#6897bb;"> </span>+ i * (-<span style="color:#6897bb;">1.6109400409995646E-6<br></span><span style="color:#6897bb;"> </span>)))))))))))))))<br>}<br><br><span style="color:#cc7832;">var </span>i = <span style="color:#6897bb;">0<br></span><span style="color:#cc7832;">while </span>(p(i)) print p(i++)<br></pre>
<p><b style="color: rgb(255, 0, 0);"><br></b></p>
<p><b style="color: rgb(255, 0, 0);">STOP</b> reading now and try it out for yourself ... or browse the <a href="https://community.oracle.com/tech/developers/discussion/1239419/java-code-obfuscation-contest" target="_blank">possible origin</a>.</p>
<p><br></p>
<p><span style="color: rgb(255, 0, 0); font-weight: bold;">SPOILER ALERT</span>&nbsp;okay, if you didn't stop, I guess it's still okay to scroll down to see what it prints out and how to create an obfuscated script yourself...</p>
<p><br></p>
<p><br></p>
<p><br></p>
<p><br></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&darr;</p>
<p><br></p>
<p><br></p>
<p><br></p>
<p><br></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&darr;</p>
<p><br></p>
<p><br></p>
<p><br></p>
<p><br></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&darr;</p>
<p><br></p>
<p><br></p>
<p><br></p>
<p><br></p>
<p>Let's Groovify the <a href="https://twitter.com/nikialeksey/status/1600598026678149120" target="_blank">reply</a> from <a href="https://twitter.com/nikialeksey" target="_blank">Alexey Nikitin</a>&nbsp;which uses&nbsp;<a href="https://commons.apache.org/proper/commons-math/" target="_blank" style="background-color: rgb(255, 255, 255);">Apache Commons Math</a>&nbsp;to replicate the problem:</p>
<pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'JetBrains Mono',monospace;font-size:9.6pt;"><span style="color:#bbb529;">@Grab</span>(<span style="color:#6a8759;">'org.apache.commons:commons-math3:3.6.1'</span>)<br><span style="color:#cc7832;">import </span>org.apache.commons.math3.analysis.interpolation.NevilleInterpolator<br><br><span style="color:#cc7832;">var </span>text = <span style="color:#6a8759;">'Hello, world!</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">'<br></span><span style="color:#cc7832;">var </span>size = text.size()<br><span style="color:#cc7832;">var </span>x = <span style="color:#cc7832;">new double</span>[size + <span style="color:#6897bb;">1</span>]<br><span style="color:#cc7832;">var </span>y = <span style="color:#cc7832;">new double</span>[size + <span style="color:#6897bb;">1</span>]<br><span style="color:#cc7832;">for</span>(i <span style="color:#cc7832;">in </span><span style="color:#6897bb;">0</span>..<size) {<br> x[i] = i<br> y[i] = (<span style="color:#cc7832;">int</span>) text[i]<br>}<br>x[size] = size<br>y[size] = <span style="color:#6897bb;">0<br></span><span style="color:#6897bb;"><br></span><span style="color:#cc7832;">var </span>lines = []<br><span style="color:#cc7832;">var </span>interpolator = <span style="color:#cc7832;">new </span>NevilleInterpolator()<br><span style="color:#cc7832;">var </span>function = interpolator.interpolate(x, y)<br><span style="color:#cc7832;">var </span>coeff = function.<span style="color:#9876aa;">coefficients<br></span>lines << <span style="color:#6a8759;">'char p(int i) {'<br></span>lines << <span style="color:#6a8759;">" (char) (</span>$<span style="font-weight:bold;">{</span>coeff[<span style="color:#6897bb;">0</span>]<span style="font-weight:bold;">}</span><span style="color:#6a8759;"> + 0.5"<br></span><span style="color:#cc7832;">for</span>(i <span style="color:#cc7832;">in </span><span style="color:#6897bb;">1</span>..<coeff.<span style="color:#9876aa;">length</span>) {<br> lines << <span style="color:#6a8759;">' + i * (' </span>+ coeff[i]<br>}<br>lines << <span style="color:#6a8759;">' ' </span>+ <span style="color:#6a8759;">')' </span>* coeff.<span style="color:#9876aa;">length<br></span>lines << <span style="color:#6a8759;">'''}<br></span><span style="color:#6a8759;">var i = 0<br></span><span style="color:#6a8759;">var out = ''<br></span><span style="color:#6a8759;">while(p(i)) out += p(i++)<br></span><span style="color:#6a8759;">out<br></span><span style="color:#6a8759;">'''<br></span><span style="color:#cc7832;">var </span>script = lines.join(<span style="color:#6a8759;">'</span><span style="color:#cc7832;">\n</span><span style="color:#6a8759;">'</span>)<br>println script<br><span style="color:#cc7832;">assert </span>text == Eval.<span style="color:#9876aa;font-style:italic;">me</span>(script)<br></pre>
<p>This generates the script, prints it out, and then runs it to make sure it produces what we intended. It only differs from above in that instead of printing out each character, it builds up and returns a String so that we can assert our expectations. It was simpler than capturing stdout by other means.</p>
<p>Enjoy!</p>