Ejemplo con PB/CC

Cuando escribía Ejemplo con PB/Forms, creo que la conclusión a la que llegasteis es que PowerBasic es un lenguaje bastante tedioso.

Nada más lejos de la realidad, lo que en realidad es tedioso es crear aplicaciones Windows, usando su API, y el bucle de proceso de mensajes. Algo en donde PBForms / DDT ayuda, pero que no es la panacea. Donde en realidad brilla PowerBasic, es precisamente como nos indica su nombre, en otorgar potencia a BASIC, un lenguaje tradicionalmente considerado, no por mi parte, confuso, poco eficiente, y poco potente.

Hay que recalcar que la primera implementación de punteros de verdad (con aritmética) que vi en un dialecto de BASIC, era de PowerBasic.

Para este ejemplo, he escogido Power Basic Console Compiler (PBCC), la versión de PowerBasic para Windows específica para el desarrollo de aplicaciones de consola (modo texto). En realidad he usado la última versión (6.04), pero puedes usar sin ningún problema Classic Power Basic Compiler 5.07. Con el fin de demostrar su posibilidades, he optado por implementar ROT13, el algoritmo de encriptación/ofuscación del que BiaNamaran es un gran defensor, y que tiene la particularidad que es como el de XOR, ejecutado una vez encripta, y una segunda vez, desencripta.

La idea tras él, es realmente sencilla. Vamos a sumar 13 posiciones a cada letra que nos encontremos. Así la A pasará a ser la N, la B pasará a ser la O y así sucesivamente. Cuando lleguemos a la N, lo haremos de forma circular, y esta pasará a ser la A, la O pasará a ser la B, etcétera. Es por ello, que tanto encripta, como desencripta.

Lo cierto es que es un algoritmo muy sencillo de implementar, recorreríamos la longitud de la cadena original, e iríamos sumando 13 a cada carácter que nos encontráramos. Algo así:

Function Rot13 (psString As String) As String
    Dim iCont As Integer
    For iCont = 1 To Len(psString)
        Mid$(psString, iCont, 1) = Chr$(Asc(Mid(psString, iCont, 1)) + 13)
    Next iCont
    Function = psString
End Function

Bueno, realmente no es tan fácil, fijaros que ese fragmento de código, sumaría 13 a cualquier carácter, sea éste una letra, como por ejemplo un número. El problema, es que si fuera un número, u otro caracter ASCII/ANSI, el esquema se rompería. Imaginemos el carácter 0, que tiene por código el 48. Si le sumamos 13, sería el 61, o sea el signo de igual (=). Al volver a sumar 13, cosa que nos lo debería desencriptar, tendríamos el 74, o sea la J. Ya veis que esta implementación (que he obtenido de internet), tiene el problema que no maneja la forma circular, y que no limita su operación a solamente letras.

Aquí es donde vamos a tirar de PowerBasic, y gracias a sus foros, extraigo esta implementación:

Function Rot13 (psString As String) As String
   Replace Any Chr$(Asc("A") To Asc("Z"), Asc("a") To Asc("z")) With Chr$(Asc("N") To Asc("Z"), Asc("A") To Asc("M"), Asc("n") To Asc("z"), Asc("a") To Asc("m")) In psString
   Function = psString
End Function

A diferencia de la anterior, ésta si que es completa, limitando el proceso a letras (mayúsculas y minúsculas), de manera que naturalmente, ya es circular. En el mismo foro, hay una versión aún mejor, que usa ROT13 para las letras, y ROT5 para los números. Pero lo que aquí interesa, es que PowerBasic nos ofrece la función REPLACE, que permite reemplazar un rango de caracteres por otro. O sea, nos ahorra trabajo. Gracias al modificador Any, puede operar sobre la cadena completa, por tanto nos ahorramos el bucle For. Además como internamente lo implementa de una forma mucho más eficiente que el bucle del ejemplo, el resultado será más compacto y veloz.

El código completo del programa, no tiene mucho misterio. 38 lineas meridianamente claras:

'-------------------------------------------------------------------------------------------
#Compile Exe
#Dim All
#Optimize Speed
#Optimize Code On
#Register All
#Align 16


'-------------------------------------------------------------------------------------------
Function PBMain () As Long
    StdOut  "PBROT13 R1.01 - Encrypt/Decrypt using ROT13                 Copyright (c) 2016-2017 by Javier Gutierrez Chamorro (Guti)" + $CrLf
    If Command$ = "" Then
        StdOut  "PBROT13 encrypts and decrypts strings in the command line, using simple ROT13 algorithm" + $CrLf
        StdOut  "Syntax is:"
        StdOut  "PBROT13 " + $CrLf
        StdOut  "Examples:"
        StdOut  "   PBROT13 Hello World"
        StdOut  "   Will get the encrypted string for 'Hello World'" + $CrLf
        StdOut  "   PBROT13 Uryyb Jbeyq
        StdOut  "   Will get the decrypted string for 'Uryyb Jbeyq'" + $CrLf
        StdOut  "More information at:"
        StdOut  "   https://nikkhokkho.sourceforge.io/static.php?page=PBROT13"
        StdOut  "Press ENTER to continue..." + $CrLf
        WaitKey$
        StdOut
    Else
        StdOut "Input string:  " + Command$
        StdOut "Output string: " + Rot13(Command$)
    End If
End Function


'-------------------------------------------------------------------------------------------
Function Rot13 (psString As String) As String
   Replace Any Chr$(Asc("A") To Asc("Z"), Asc("a") To Asc("z")) With Chr$(Asc("N") To Asc("Z"), Asc("A") To Asc("M"), Asc("n") To Asc("z"), Asc("a") To Asc("m")) In psString
   Function = psString
End Function

El resultado, un ejecutable de consola pequeñísimo (13.824 bytes), y muy rápido de ejecución, donde lo que más ocupa, son las funciones de la librería que se usan, pues de código, hablamos de apenas 1 Kb. (1.448 bytes):
1488 bytes compiled code, 8480 bytes RTLibrary,
704 bytes string literals, and 3344 bytes dgroup.
Disk image: 13824 bytes Memory image: 12528 bytes.

Para asegurarme que todo funcionaría bien con la versión gratuita, también lo he compilado con ella, como curiosidad, los resultados fueron aún más pequeños:
1228 bytes compiled code, 6549 bytes RTLibrary,
688 bytes string literals, and 2556 bytes dgroup.
Disk image: 11776 bytes Memory image: 9793 bytes.

Muchas veces nos quejamos del bloatware, ese software que cada nueva versión es más lento. Ya veis que no es el caso. Tras 3 años de PBCC, el aumento de peso ha sido de menos de 2 Kb. entre uno y otro, ofreciendo a cambio multitud de nuevas funciones.

Tal vez os llame la atención WaitKey$, una función que espera la pulsación de una tecla y la devuelve. Seguramente no la habíais visto en ningún BASIC clásico, y os suena InKey$, que nos obligaba a comprobar si ya había tecla o no. Pues ya veis, otro ejemplo de su potencia.

Pero lo más destacable es que uso StdOut, en vez del Print que todos conoceréis. Esto es porque StdOut, soporta redirecciones estándar a fichero, y Print no. En el caso de haber usado Print, se podría haber reducido en casi 1 Kb. más.

Si todo esto te parece poco, decirte que los programas que crees, funcionarán desde Windows 95, hasta Windows 10. ¿Alguien ofrece tanto hoy en día?

En resumen, PowerBasic es facilidad de programación, potencia, y código eficiente. Pero además, como lo puedes conseguir gratuitamente, es además indispensable.

Aquí tienes los binarios y el fuente para descargar (14 Kb. en formato ZIP).

Ejemplo con PB/CC

10 comentarios en “Ejemplo con PB/CC”

  1. Me gustan las cosas simples que funcionan bien, como ROT13 es un buen ejemplo de encriptación sin complicación, quizá por eso me gusta.

    El segundo ejemplo me gusta mucho, se ven las letras bien claritas y diciéndole al programa: “no me salgas de ahí, eh?” 😀

    Por desgracia todo este tipo de herramientas están intentando que pasen a la historia, con sistemas como Windows 10 Cloud y Android, donde lo que interesa es que vayas a la tienda de aplicaciones, eso de crear programas y ejecutarlos luego independientemente de las versiones del sistema operativo parece que ha caído en el olvido. Ahora es todo lo contrario, cuanto más puedan restringuir su ejecución y uso, mejor -para ellos, porque más control tienen-. Dicen que eso es para aumentan la seguridad. No está muy claro si la nuestra como usuarios, o la de ellos.

  2. Javier Gutiérrez Chamorro (Guti)

    Igual yo BiaNamaran. Cuando necesitas salir del paso, te valo algo simple y que funcione. Si además es eficiente, y no te condiciona, como por ejemplo PowerBasic, es casi la herramienta perfecta.

    Me doy también cuenta de los derroteros por donde va la tecnología. Y llegará un punto en que los ordenadores, sólo serán capaces de ejecutar programas, un poco como las consolas. Para programarlos, necesitaremos un hardware especial y un SDK. Llegados a ese punto, ya no podremos denominarlos ordenadores, porque la clave de un ordenador, es que sea programable.

  3. Javier Gutiérrez Chamorro (Guti)

    Los ejecutables que genera son para Windows de 32 bits. Siendo compatibles desde Windows 95, hasta Windows 10, algo que muy pocas herramientas de desarrollo ofrecen. Además teniendo versiones gratuitas como las de Classic Powerbasic, no pierdes nada por probarlas.

    Si te interesa crear aplicaciones para DOS, tienes Powerbasic for DOS, aunque a diferencia de PB/CC, y PB/Win, no ofrece de momento versión gratuita. En muchos casos, podrás incluso compilar un programa para DOS de PB/DOS a Windows con PB/CC sin necesidad de realizar cambios. Lo contrario, es decir, convertir un programa Windows escrito en PB/CC a DOS con PB/DOS, no suele ser tan sencillo.

  4. Hola Guti. Espero estes muy bien. en el pasado me has ayudado con mi aprendizaje con PBCC 6.03, te molesto para pedirte si me puedes enviar ejemplos de como usar las imagenes BMP en PBCC, siento mucho molestarte pero por mas que trato no entiendo como crear, guardar y cargar las imagenes en mis pobres programa que hago para mi uso personal. muchas gracias por lo que puedas hacer por mi.

  5. Javier Gutiérrez Chamorro (Guti)

    Por supuesto que sí Crispin Nuñez, aunque tendrás que ser más concreto en cuanto a lo que necesitas, la parte que ya conoces y lo que te falta.
    De momento y para familiarizarte con el formato puedes leer el artículo de la Wikipedia. Verás que es una estructura sencilla y que como la mayoría de variantes van sin comprimir es relativamente fácil de tratar.

  6. Buenas Guty. Perdona que te moleste. aun tengo el problema de como pasa imagenes BMP a PBCC 6.03. lo que no se es si tengo imagenes BMP en ambiente Windows como las puedo pasar a un Archivo en la Consola PBCC para guardarlas para su posterior uso. Si me puedes ayudar te lo agradezco mucho de lo contrario igual agradezco tu tiempo. Gracias

  7. Javier Gutiérrez Chamorro (Guti)

    No sé si me ha quedado demasiado claro Crispin Nuñez, entiendo que lo que quieres es guardar en disco un archivo BMP con una imagen que hayas generado tu. En ese caso, hay varias cosas que deberías conocer:
    1) Activar el modo gráfico y dibujar en él.
    2) Recorrer los píxeles de la pantalla.
    3) Manejar archivos binarios.
    4) Comprender la estructura del formato BMP (ese es el enlace que te puse más arriba).

    Con cual de los puntos tienes dificultades?

Deja un comentario