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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
'-------------------------------------------------------------------------------------------
#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 <string>" + $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  "   http://nikkhokkho.sourceforge.net/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).