Thursday, December 11, 2014

Is that good or bad?

This is the type of achievement to hide in a CV :(

Edit (2015-01-05): New hit on Stackoverflow!

Friday, December 5, 2014

Obfuscating Python code


WARNING!!!:
Obfuscating code is probably a bad idea. It can have unpredicted consequences. Think twice before continuing


The script:
Next shell script will serve as reference to obfuscate Python code by compiling original files to .pyo while hiding the original source from py files.


#!/bin/sh
# DIR_L: directory list (module list)

DIR_L="pythonModule1 pythonModule2 pythonModule3"

CWD=`pwd`
for dirA in ${DIR_L}; do
    cd ${CWD}/${dirA}
    rm -f *pyc *pyo
    python -OO -m compileall .
    ls *py | while read f ; do
        # Create empty "file".py with same modification time
        #
that tmp (the renamed original "file".py used to
        # create the pyo file)
        mv $f tmp && touch -r tmp $f && rm tmp
    done
done



Explanation:
 Python will *always* compare the modification date of the *py file with the one hardcoded in the *pyo object. If it doesn't match, the pyo will be recreated.
Creating a pyo file and then removing the code in the original *py file will not work since once the code is removed (echo -n "" > myfile.py) the modification date is updated. Next run will update the pyo file from the empty py file.
 Removing the py file leaving only the pyo file will not work either, since python will ignore the pyo file if the matching py file is not present.

The quick-and-easy solution then is to use "touch" with the -r option. This combination will create an empty file and update the creation/modification timestamp of the new file taking as reference the file passed to "-r".  Since moving a file doesn't modify its modification timestamp a line similar to:

  mv myfile.py tmp && touch -r tmp myfile.py && rm tmp 

will create the empty myfile.py with a modification timestamp matching that of the myfile.pyo (created previously using python -OO -m compileall .)

While not shown in the script it's pretty clear that we must be working with a copy of the original sources. Otherwise they will be lost after obfuscation. Is up to the reader to choose its favourite way to do the copy. As a hint I use something like the next one-liner:

tar -C src_dir -cf - * | tar -C working_dir -xf -

Alternatives:
pyminifier  provides utilities to minify, obfuscate and compress Python code as well as a Python API to use it inside other Python code. Unfortunately in my own tests it was buggy with many cryptic errors about missing modules.

Notes:
touch is just available on UNIX-POSIX friendly systems. Probably it will also work on Windows with the help of cygwin, but it's not tested at all (and it will never be!).


Thursday, May 29, 2014

How much time does it takes to scan the entire Internet?

One week?, One month?


Extracted from https://github.com/robertdavidgraham/masscan

"This is the fastest Internet port scanner. It can scan the entire Internet in under 6 minutes, transmitting 10 million packets per second."

All you need is some good idea to start hacking the Internet and a 10Gbit/s symmetric link. Just ask your local carrier about it.


Sunday, May 4, 2014

Spontaneus symetry breaking of prime numbers.



Let's imagine for a moment that we start adding "+1" for each natural number. Whenever we reach a prime number we switch the sum from "+1" to "-1".  If prime numbers are randomly distributed we expect the total sum to oscillate around 0.
Take for example the first 20 numbers (in bold prime numbers, where we start switching back):

                                        | Total
    3       3                           |
  2   2   2   2                         |
1       1       1       1               |
------------------0---0---0--------------
                   -1      -1      -1   |
                             -2  -2  -2 |
                               -3       |
                                        |
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 |
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 |
    *   *   *       *   *       *   *   |



 Let's see what we get in practice.


Next python code simulate the previous process/algorithm/"thing":


  1 def isprime(n):
  2     n*=1.0
  3     if n%2==0 and n!=2 or n%3==0 and n!=3:
  4         return False
  5     for b in range(1,int((n**0.5+1)/6.0+1)):
  6         if n%(6*b-1)==0:
  7             return False
  8         if n %(6*b+1)==0:
  9            return False
 10     return True
 11
 12 START=1
 13 total=0
 14 sum = -1
 15 for END in xrange(5000000,30000001,5000000):
 16     totalNeg=0
 17     totalPos=0
 18        
 19     for i in xrange(START, END):
 20         total = total + sum
 21         if total > 0:
 22             totalPos += 1
 23         if total < 0:
 24             totalNeg += 1
 25         if isprime(i):
 26             sum  = -1 * sum
 27     START = END+1
 28    
 29     rat = totalPos*1./totalNeg
 30     if rat > 1:
 31        rat = 1./rat
 32     
 33     print total, total*1./END, totalPos, totalNeg, rat


Every 5000000 numbers we print some statistics (line 33).



In the program output, the first column prints the "total" variable, which shows the total sum at a given time. We expect such column to be evenly distributed between negative and positive numbers. The second column shows the ratio between the total sum and the current natural number, that we expect to be close to zero. The third column will show how many times the total sum was possitive, with the fourth column showing how many times it was negative, finally the fith column shows the ratio between the times the total sum was possitive and the time it was negative. We expect column 3 to be quite similar to column 4, and so fith column close to 1.


Let's see what our program shows in practice:

SUM    Current / SUM    
-1757  -0.00292833333333 90292  509554 0.177198

-3393  -0.00308454545455 90292 1009554 0.089437
-6197  -0.003873125      90292 1509554 0.059813
-9685  -0.0046119047619  90292 2009554 0.044931
-10401 -0.00400038461538 90292 2509554 0.035979


Not exactly the result I was waiting for. Intuition failed (as is always the case with prime numbers). The sum never oscillates and cross back to zero creating what scientifics will call an spontaneous break of symmetry.



Saturday, May 3, 2014

C++ or C--?


Copy&Paste from "Expert C programming, Deep secrets":

"If you think C++ is not overly complicated, just what is a protected abstract virtual base pure virtual private destructor, and when was the last time you needed one?"

In the mean time C is a great language with all its "buts" !

Update: 2015-03
Defective C++ is worth reading before adventuring into the C-- nightmare.

Wednesday, August 7, 2013

Asynchronous JS the easy way



The objective:
To be able to call MyWidget.redraw(onRedrawCallback,...) without worrying about the previous (initialization) state of our MyWidget instance.

The code:

  1 MyWidget = {
  2     template : false,
  3     myPreciousData : false,
  4     ...
  5     __load_template : function (url, dstVar, callback, callbackArgs)
  6     {
  7         ...
  8         onResponse : function (...) {
  9             if (callback) { callback(callbackArgs); }
 10         }
 11     },
 12     ...
 13     __get_data : function (callback, callbackArgs)
 14     {
 15         ...
 16         onResponse : function (...) {
 17             if (callback) { callback(callbackArgs); }
 18         }
 19     },
 20     ...
 21     redraw : function(callback, callbackArgs)
 22     {
 23         if (!MyWidget.template){
 24             MyWidget.__load_template( MY_TEMPLATE_URL , MyWidget.template, MyWidget.redraw /*"recursive*/ );
 25             return;
 26         }
 27         if (!MyWidget.myPreciousData){
 28             MyWidget.__get_data(MyWidget.redraw /*callback to our own function */, false, false);

 29             return;
 30         }
 31         if (! document.getElementById("myContainer") {
 32             MyWidget.__setUpContaier(MyWidget.redraw);

 33             return;
 34         }

 35         /* At this point all Object data (template, myPreciousData, container,...)
 36          * has been initialized. */
 37         ...
 38         if (callback) { callback(callbackArgs); }

 39     }...
 40 }
 41
 42 var postRedrawFunct = function (...) {
 43 }
 44
 45 }
 46 myGUIElment.onClick(MyWidget.redraw(postRedrawFunct, ...)); // Just call redraw.

Saturday, July 20, 2013

The war against bugs is not lost!


Extracted from "Professional Linux Kernel Architecture" (Wolfgang Mauerer):


For comparision of the CPU quality, here is the check_bugs routine of S390, Alpha, Extensa, H8300, v850, FRV, Blackfin, Cris, PA-RISC, and PPC64:

static void check_bugs(void)

The S390 kernel is among the most confident ones, as you can see in the following code:

include/asm-s390/bugs.h

static inline void check_busgs(void)
{
  /* s390 has no bugs ... */
}