En mis clases en la UNAM les advierto a mis estudiantes que no copien los programas porque me voy a dar cuenta. De hecho, aunque cambien los nombres de las variables (al español, por ejemplo), de un programa encontrado en Internet, la lógica del mismo se mantiene intacta y que eventualmente tengo mecanismos para identificar si el autor del código es el estudiante o bien una copia encontrada en la red. Puede ser que alguien logre engañarme, pero la realidad es que el alumno se engaña a sí mismo porque no aprende. ¿Y por qué digo esto? Porque alguien ya encontró una metodología para identificar a los programadores a partir de su código ejecutable incluso, lo cual me parece notable.
Los programadores tienen diferentes estilos todos, pero podría esperarse que el estilo desaparece en cuanto el programa se compila a código ejecutable. Los estilos tienen que ver con cómo nombra sus variables, cómo usa o pone comentarios, así como otros detalles importantes. Muchas son las preferencias personales que de alguna manera se borran cuando se compila el código, pero otras quedan intocables y parecen ser suficientes para identificar al programador y esto en el fondo puede tener muchas consecuencias.
El estudio tomó el código de 600 programadores de una competencia anual, el Google Code Jam. La habilidad de los programadores se midió observando qué tan lejos llegaron en la competencia. El código ejemplo se escribió todo en C++ en donde se trataba de resolver el mismo problema de programación y aquí es donde ocurrieron las principales diferencias entre el código y el estilo, pudiendo atribuir quién escribió qué código a partir de ello.
Encontrar al programador que escribió una pieza de código específica se puede tratar como un problema de aprendizaje de computadora, lo cual es en esencia el problema. La primera tarea fue extraer las características y esto se hizo desensamblando el código y decompilando de nuevo al lenguaje original C++. Los detalles de cómo se hizo esta ingeniería en reversa son interesantes y están dados en el artículo publicado. También se generó un árbol sintáctico abstracto y una gráfica de control de flujo que se usó para observar ciertas características. En lugar de usar una red neuronal, un clasificador azaroso fue usado para aprender las características de cada programador de los códigos reconstruidos a mano.
Los resultados son impresionante. La clasificación de 20 programadores fue posible entonces, con un porcentaje de acierto del 96%. El clasificador fue entrenado en 8 ejecutables para cada programador, lo que representa muchos ejemplos en este tipo de estudios. Cuando se trató de identificar a todos los programadores (600), la precisión cayó a un 52%. Se demostró que para una compilación no optimizada de 100 programadores, la precisión fue de 78% pero cuando se optimizó ésta la precisión decayó al 64%. Esto tiene lógica: un optimizador de código debe quitar más características personales del código binario.
Otros resultados muestran que en la medida que el programador es más avanzado, más fácil es de reconocer, comparado con los principiantes. Esto sugiere que estos últimos tienden a codificar de la misma manera mientras que los programadores expertos son más individualistas y el estilo de su código es más notable. El siguiente video da detalles del artículo si es que el lector/a no quiere leerlo.
Pero ¿por qué esto podría importar? Aparte del resultado interesante en donde se demuestra que el estilo sobrevive a la compilación del código, podría ser útil en la ciencia forense digital. Si usted planea escribir código malicioso entonces asegúrese de que no deja otros programas accesibles porque podría sino ser identificado. Igualmente, la identificación del programador podría ayudar a disputas sobre quién hizo qué en el desarrollo de una empresa exitosa. Quizás podríamos entonces saber qué tanta cantidad de código escribió Mark Zuckerberg para Facebook o identificar finalmente a Satoshi Nakamoto, el aparente pseudónimo del inventor del BitCoin.
Tal vez en la práctica sea más difícil pero claramente el código tiene, como la letra manuscrita, un identificador personal del cual uno no puede zafarse. Vamos, hasta la manera de cómo escribimos una contraseña en el teclado puede identificarnos.
Referencias: