:: El Monstruillo wARfeando ::

Clase acceso a bases de datos *.mdb (MS Access)

August 7th, 2007

Hace poco me ví en la necesidad de acceder a unas tablas en unas bases de datos access (*.mdb) y acabé escribiendo esta entrada.

Es sencillo y funciona, como digo al final de la entrada, pero es engorroso a más no poder de modo que acabé escribiendo una pequeña clase para conectar con una base de datos access, hacer consultas (SELECTS, INSERTS, UPDATES … vamos cositas básicas).

Aquí hay un zip con la cabecera y el cuerpo de la clase.

Para comenzar a utilizarla, como ya dije en la entrada anterior hay que enlazar el programa con la biblioteca odbc32.lib. Además de eso es probalbe que debais cambiar algún #include <> para amoldarlo a donde pongais los archivos. Yo siempre uso una estructura de directorios del tipo de src\headers y src\fonts de modo que el #include en el cuerpo de la clase aparece #include “..\headers\accessdb.h”.

Una breve explicación de uso de la biblioteca.

Lo primero que se debe hacer es crear el objeto AccessDB para establecer la conexión y lanzar las consultas:

AccessDB conn;

Una vez tenemos el objeto conn creado ya podemos establecer la conexión (capturando errores):

if (conn.fileConnect(pathToMDBFile) < 0) {

char errstr[1024];

conn.getStrError(errstr);

// se hace lo que sea con este errstr

return -1; // por ejemplo

}

Ahora ya estamos conectados y podemos lanzar consultas SQL a diestro y siniestro

conn.sendQuery(”SELECT * FROM tablilla_molona”); // si devuelve < 0 se ha producido un error

En este caso es conveniente recoger los datos para hacer luego con ellos lo que quieras. sendQuery, cuando se usa con un SELECT genera una tabla de resultados de f filas por c columnas (una tabla FxC) y para obtener los datos de ella se hace del siguiente modo:

// vamos a rellenar una listview (por ejemplo) con todos los datos encontrados:

int filas = conn.getRows();

int cols = conn.getCols();

for (int f=0; f < filas; f++) {

for (int c=0; c < cols; c++) {

char valor[1024];

conn.getData(f, c, valor);

// aquí haríamos algo con valor

}

}

Una vez hecho todo solo queda desconectar la conexión:

conn.Disconnect();

Y con esto y un bizcocho… espero que os sea de utilidad a alguno. Y si lo ampliáis o mejoráis de algún modo no dejéis de notificármelo y pasarme el nuevo código que estaré encantado de colgarlo.


Access, ODBC y WinAPI

May 9th, 2007

¿Cómo acceder a bases de datos de MS Access desde ODBC usando las WinAPI?

Para comenzar se debe enlazar la biblioteca odbc32.lib e incluir las cabeceras sql.h, sqlext.h y sqltypes.h.

Una vez echo esto ya se puede comenzar a llamar a las funciones de la ODBC API.

Para establecer una conexión ODBC con un archivo .mdb (MS Access) hay que seguir estos pasos:

1. Alojar memoria para un entorno ODBC e inicializarlo.
SQLHENV env; // El entorno
SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
// ret = { SQL_SUCCESS | SQL_SUCCESS_WITH_INFO | SQL_INVALID_HANDLE | SQL_ERROR }
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
2. Alojar memoria para un manejador de conexión y realizar la conexión.
SQLHDBC dbc; // El manejador de conexión
ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
ret = SQLDriverConnect(dbc, (HWND)NULL, (SQLCHAR *) “DRIVER={Microsoft Access Driver (*.mdb)};, SQL_NTS, DBQ=D:\\basedatos.mdb”, outConnStr, outConStrLen, &retOutConnStrLen, SQL_DRIVER_COMPLETE);
// ret = { SQL_SUCCESS | SQL_SUCCESS_WITH_INFO | SQL_NO_DATA | SQL_INVALID_HANDLE | SQL_ERROR }

Una vez tenemos el manejador de conexión podemos comenzar a lanzar sentencias SQL sobre esta conexión, para ello seguiremos los siguientes pasos:

1. Alojar memoria para el manejador de sentencias:
SQLHSTMT stmt;
ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
2. Crear y lanzar la sentencia SQL:
SQLCHAR sentencia[1024];
char tabla[] = “variable”; // o lo que sea, es solo una excusa para crear la sentencia :P
sprintf(sentencia, “SELECT * FROM %s”, tabla);
SQLExecDirect(stmt, sentencia, sizeof(sentencia));
3. Recuperar los datos si los hay:
SQLSMALLINT columns;
SQLNumResultCols(stmt, &columns);
// Ahora vamos fila por fila sacando las columnas
while (SQL_SUCCEEDED(SQLFetch(stmt))) {
SQLUSMALLINT i;
for (i=0; i <=columns; i++) {
char buf[1024];
SQLINTEGER len;
ret = SQLGetData(stmt, i, SQL_C_CHAR, buf, sizeof(buf), &len);
if (SQL_SUCCEEDED(ret)) {
if (len == SQL_NULL_DATA) strcpy(buf, “NULL”);
// AHORA EN “buf” tenemos un dato tratable como una cadena obtenido de la base de datos
}
}
}
El “ret” de SQLGetData puede ser (SQL_SUCCESS | SQL_SUCCESS_WITH_INFO | SQL_NO_DATA | SQL_STILL_EXECUTING | SQL_ INVALID_HANDLE | SQL_ERROR).
4. Se liberan los manejadores, en este mismo orden:
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);

Bien sencillo y funciona.
Ale.


Poner un icono en la TrayIcon con WinAPI

March 17th, 2007

¿Cómo hacer lo mismito que hace el Messenger o el Skype para poner su iconcico en ese rectangulito al lado de la hora en la barra de Windows (a partir de ahora ‘TrayIcon’, para abreviar)?

Hace poco vi en GetAFreeLancer.com la petición de alguien para hacer un programa que entre otras cosas se “iconificara” en la trayicon y me pregunté ¿cómo haría yo eso? así que me puse a investigar un poco (¡viva google y las MSDN!) y esto es lo que saqué en claro:

Lo primero que se necesita para poder poner el icono de una aplicación en la trayicon es tener una aplicación con icono… :P.

Para poner un icono vamos a necesitar unas estructuras de datos y unas funciones que se encuentran en shell32.lib (o shel32.dll si os van más las dlls) con los prototipos de las funciones en shellapi.h, de modo que hay que hacer que el compilador enlace esta librería y hay que añadir el include para . Además vamos a necesitar definirnos un mensaje para que se comuniquen el iconillo en el trayicon y nuestra aplicación, esto podemos hacerlo así:

#define MSG_TRAYICON WM_USER + 1

Mediante este mensaje el icono del trayicon le notificará a la aplicación los eventos de ratón que se hagan en su área (no se si le notificará más eventos, como alguno de teclado, he leido tanto que no lo hará como que sí, pero no lo he probado me queda pendiente hacerlo).

Vamos a suponer que tenemos un botoncico que al hacer click sobre él, la aplicación se nos iconifica en el trayicon y que luego, al hacer doble click con el botón derecho sobre el icono la aplicación vuelve a mostrarse y el iconillo del trayicon desaparece. Y vamos a suponer que el botoncico tiene un identificador tal que así: IDICONIFICAR.

Entonces, en la función de gestión el bucle de mensajes principal (WndProc) después de capturar el mensaje de el WM_COMMAND (donde se caputra el click en los botones) tendríamos algo así para capturar el click en IDICONIFICAR:

switch(LOWORD(wParam)) {

case IDICONIFICAR:

NOTIFYICONDATA data;

data.cbSize = sizeof(data);
data.hWnd = hWnd;
data.uID = 10001;
data.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICONCILLO));
data.uFlags = NIF_ICON|NIF_TIP | NIF_MESSAGE;
strcpy(data.szTip, “Estoy iconificao, hazme doble click”);
data.uCallbackMessage = MSG_TRAYICON;

Shell_NotifyIcon(NIM_ADD, &data);
ShowWindow(hWnd, SW_HIDE);
break;

// … demás botones

}

Con la estructura NOTIFYICONDATA preparamos el iconillo que pondremos en el trayicon:data.cbSize es para proveer algo de seguridad a la hora de leer luego la estructura (si no se pone, no funciona porque no leera nada), data.hWnd es ventana de la aplicación que se iconificará, data.uID es un identificador para el icono en el trayicon, data.hIcon es el manejador del icono que se pondrá en el trayicon, data.hTip es el mensaje que se mostrará al dejar el puntero del ratón sobre el icono durante un momentito, data.uCallbackMessage es el mensaje que hemos creado para que se comuniquen el icono en la trayicon y la aplicación y data.uFlags indica a que campos de la estructura data se va a hacer caso, en este caso al icono, al tip y al mensaje que compartirán.

Una vez cargada la estructura usamos Shell_NotifyIcon() para actuar sobre trayicon, se usa esta función tanto para añadir (NIM_ADD), como para modificar el icono (NIM_MODIFY) o para quitarlo (NIM_DELETE). Como veis se le pasa la acción (NIM_*) y la estructura. Después de esto, o antes, según os apetezca se esconde la aplicación (poner el icono en el trayicon no hace que la aplicación desaparezca de la pantalla, hay que quitarla) con ShowWindow(hWnd, SW_HIDE).

Vale, en este punto la aplicación ya es capaz de “iconificarse”, pero ¿cómo hacemos para volverla mostrar cuando hago doble click con el botón izquierdo sobre el icono (por poner un ejemplo)?

Pues en la misma función de control del bucle de mensajes (WndProc, por ejemplo), cuando se capturan los mensajes (switch(message)) como WM_COMMAND, WM_INITDIALOG, etc… Aquí podemos añadir algo así:

case MSG_TRAYICON:

NOTIFYICONDATA data;

data.cbSize = sizeof(data);
data.hWnd = hWnd;
data.uID = 10001;

// El mensaje enviado por el icono está en lParam
switch (lParam) {
case WM_LBUTTONDBLCLK:
Shell_NotifyIcon(NIM_DELETE, &data);
ShowWindow(hWnd, SW_SHOW);

}
break;

}

Ale, así de simple…


Manejar BLOBs en MySQL con Perl

February 14th, 2007

Antes que nada hay que explicar lo que es un BLOB: Un BLOB es un tipo de datos SQL y su nombre viene de Binary Large OBject y teneis algo más de infromación en la Wikipedia.

Al principio me daba un poquillo de miedo atacar este tipo de datos y no estaba seguro de que fuera buena idea, pero después de ir leyendo por ahí (no encuentro ahora los links) me acabé convenciendo de que es una buena idea, primero porque te ahorras i-nodes, en lugar de usar un i-node por cada archivo usas un par de i-nodes para todos al estar en una base de datos. Y además con esto, y al ser archivos multimedia plenamente soportados en todos los sitemas operativos, esto hace más fácilmente portable la aplicación. Además de eso, resulta que es facilón.
Bueno, anem per feina.

Lo primero importar el módulo para manejar bases de datos en Perl, yo uso DBI con el DBD_MySQL y si necesitas saber el tipo del archivo como ocurre en mi caso puedes importar también el File::MMagic:

use DBI;

use File::MMagic;

Y suponemos que tenemos una base de datos con una tabla archivos tal que así:

nombre VARCHAR(255) NOT NULL DEFAULT “”

tipo VARCHAR(50) NOT NULL DEFAULT “”

datos BLOB NOT NULL

Hecho esto continuo con el modo de insertar y hacer un update sobre un campo BLOB:

# Antes que nada nos conectamos a la base de datos

$conn = DBI->connect(”dbi:mysql:base_de_datos:servidor”, “usuario”, “contraseña”) or die “Lerele: $!”;

# Seguidamente abrimos el archivo, le sacamos las entrañas binarias y lo cerramos, después obtenemos el tipo de archivo

open($archivo, $nombre_archivo);

read($archivo, $las_entranyas, -s $archivo);

close($archivo);

$mm = new File::MMagic;

$tipo = $mm->checktype_filename($nombre_archivo);

# Después preparamos la sentencia sql y la lanzamos:

$conn->prepare(”INSERT INTO archivos (nombre, tipo, datos) VALUES(?, ?, ?)”)->execute($nombre_archivo, $tipo, $las_entranyas);

$conn->disconnect;

y es así de sencillo, es igual para hacer un UPDATE.

En caso de querer obtener uno de los archivos y mostrarlos via web, como me ha tocado hacer en el trabajo, es sencillo igualmente. Supongamos que quieres obtener el archivo bocata_atun.jpg y mostrarlo en tu web, el programita quedaría una cosa así, ojo que ni estoy controlando los posibles errores ni nada, ni siquiera uso un perl estricto, antes tampoco:

#!/usr/bin/perl

use DBI;

#notad que aquí no se usa el File::MMagic, ni falta que hace, ya tienes almacenado el tipo.

$nombre = “bocata_atun.jpg”;

$conn = DBI->connect(”dbi:mysql:basedatos:servidor”, “usuario”, “contraseña”);

$query = $conn->prepare(”SELECT tipo, datos FROM archivos WHERE nombre=’$nombre’”);

$query->execute;

($tipo, $datos) = $query->fetchrow_array;

$query->finish;

# Llega la hora de mostrar ese delicioso bocata de atún:

print<

content-type: $tipo

content-disposition: filename=$nombre

$datos

EOT

Ale es así de sencillo, eso sí notad que entre la cabecera (los content-*) y los $datos hay un \n. Y yo sin haberlo probado antes.

Posted in Perl | 1 Comment »

EAN-13

October 27th, 2006

Sigo con otra simbología de los códigos de barras, el EAN-13. Este es el que más nos puede sonar a todos ya que lo podemos encontrar en cualquier comercio. Este es que el cajero o la cajera pasa por el lector cuando vamos a un supermercado.

Esta simbología codifica números de hasta 12 dígitos y es un pelín más complicado que el Code 39 y que el Interleaved 2 of 5 porque requiere un poco más de trabajo.

Un código de barras EAN-13 está dividido en tres partes:

  1. El número de sistema.
  2. El código del fabricante.
  3. El código del producto.
  4. El dígito de control

El número de sistema consiste en dos dígitos (a veces son tres) que identifican la autoridad numeradora del país o de la región económica que le asignó el código del fabricante al fabricante o distribuidor.

00-13: USA & Canada 20-29: In-Store Functions 30-37: France
40-44: Germany 45: Japan (also 49) 46: Russian Federation
471: Taiwan 474: Estonia 475: Latvia
477: Lithuania 479: Sri Lanka 480: Philippines
482: Ukraine 484: Moldova 485: Armenia
486: Georgia 487: Kazakhstan 489: Hong Kong
49: Japan (JAN-13) 50: United Kingdom 520: Greece
528: Lebanon 529: Cyprus 531: Macedonia
535: Malta 539: Ireland 54: Belgium & Luxembourg
560: Portugal 569: Iceland 57: Denmark
590: Poland 594: Romania 599: Hungary
600 & 601: South Africa 609: Mauritius 611: Morocco
613: Algeria 619: Tunisia 622: Egypt
625: Jordan 626: Iran 64: Finland
690-692: China 70: Norway 729: Israel
73: Sweden 740: Guatemala 741: El Salvador
742: Honduras 743: Nicaragua 744: Costa Rica
746: Dominican Republic 750: Mexico 759: Venezuela
76: Switzerland 770: Colombia 773: Uruguay
775: Peru 777: Bolivia 779: Argentina
780: Chile 784: Paraguay 785: Peru
786: Ecuador 789: Brazil 80 - 83: Italy
84: Spain 850: Cuba 858: Slovakia
859: Czech Republic 860: Yugloslavia 869: Turkey
87: Netherlands 880: South Korea 885: Thailand
888: Singapore 890: India 893: Vietnam
899: Indonesia 90 & 91: Austria 93: Australia
94: New Zealand 955: Malaysia 977: International Standard Serial Number for Periodicals (ISSN)
978: International Standard Book Numbering (ISBN) 979: International Standard Music Number (ISMN) 980: Refund receipts
981 & 982: Common Currency Coupons 99: Coupons

El código de fabricante es un código único asignado a un fabricante por la autoridad numeradora del país o de la región económica. Todos los productos creados por este fabricante deben usar el mismo código de fabricante.
EAN-13 usa códigos de fabricante de longitud variable, por lo general la longitud del código de fabricante que se le asigne a una empresa dependerá de la cantidad de clases productos que fabrique y de la estimación de nuevas clases de productos que pueda fabricar. Esto significa que, si un fabricante de un país donde el número de sistema tiene dos dígitos tiene un código de fabricante de 5 dígitos, puede tener hasta 100.000 clases de productos diferentes (del 0 al 99.999).

El código de producto es un código úncico asignado por el fabricante, como la autoridad numeradora ya ha dado un código de fabricante único se garantiza que el símbolo creado será también único. En este caso, el fabricante es el encargado de que no se dupliquen los códigos de productos.

El dígito de control es un dígito adicional (que una vez calculado se añade al final del número que queremos codificar, creando un número final de 13 dígitos) usado para verificar que el código de barras ha sido escaneado correctamente. El método para calcular el dígito de control es el siguiente:

  1. Si el número a codificar no tiene 12 dígitos se añaden ceros a la izquierda hasta tener los 12 dígitos.
  2. Ahora consideramos que el primer dígito está en una posición “par” y se asignan posiciones “impar” y “par” alternativamente a los demás dígitos de izquierda a la derecha.
  3. Se suman todos los dígitos en posición “impar” y se multiplican por 3.
  4. Se suman todos los dígitos en posición “par”.
  5. Se suman los resultados de (3) y (4).
  6. El dígito de control es la diferencia positiva entre el resultado de (5) y el número divisible entre 10 inmediatamente superior al resultado de (5). Si el resultado de (5) ya es divisible entre 10, entonces el dígito de control es 0, no 10.

Un ejemplo clarificador, el número 490178019073 (el de una caja de disquetes que tengo sobre la mesa):

  • Se suman las posiciones “impares” y se multiplican por 3: 9+1+8+1+0+3=22 22×3=66
  • Se suman las posiciones “pares”: 4+0+7+0+9+7=27
  • Se suman los totales 66+27=93
  • Se busca el número inmediatemente superior a 93 divisible entre 10 y se le resta 93: 100-93=7
  • Por lo que 7 es el dígito de control y ya tenemos el número a codificar: 4901780190737

Una vez que tenemos el número de 13 dígitos, ya podemos crear su símbolo.

Un símbolo EAN-13 tiene la estructura física siguiente:

  • Marca de inicio, codificada como: 101
  • Segundo dígito del número de sistema.
  • Los 5 siguientes dígitos del número a codificar (puede ser el código de fabricante si este tiene 5 dígitos).
  • Marca central, codificada como: 01010
  • Los 6 dígitos restantes del número a codificar, incluido el dígito de control.
  • Marca de final, codificada como 101

Antes de continuar es necesario hacer saber que hay diferencias de codificación entre los dígitos de la izquierda de la marca central y los dígitos de la derecha de dicha marca. En la parte izquierda hay dos tipos de codificación, dos paridades “par” e “impar”, esto es así porque el primer dígito del número de sistema se codifica en la paridad de los últimos 5 dígitos de la parte izquierda.

DIGITO Cod. Izquierda IMPAR Cod. IzquierdaPAR Cod. DerechaTODOS
0 0001101 0100111 1110010
1 0011001 0110011 1100110
2 0010011 0011011 1101100
3 0111101 0100001 1000010
4 0100011 0011101 1011100
5 0110001 0111001 1001110
6 0101111 0000101 1010000
7 0111011 0010001 1000100
8 0110111 0001001 1001000
9 0001011 0010111 1110100
Num. Sist1er Dig Num. Sist2o Dig 1 2 3 4 5
0 Impar Impar Impar Impar Impar Impar
1 Impar Impar Par Impar Par Par
2 Impar Impar Par Par Impar Par
3 Impar Impar Par Par Par Impar
4 Impar Par Impar Impar Par Par
5 Impar Oar Par Impar Impar Par
6 Impar Par Par Par Impar Impar
7 Impar Par Impar Par Impar Par
8 Impar Par Impar Par Par Impar
9 Impar Par Par Impar Par Impar

Ahora voy con un ejemplo de codificación, el número de antes era 4901780190737., pues voy a por él:

  1. Paridad con la que codificar el primer dígito del número de sistema (P: par, I: impar): 4 –> PIIPP
  2. Marca de inicio: 101
  3. Segundo dítigo del número de sistema, siempre con paridad impar, no lo indica el primer dígito: 9 –> 0001011
  4. Primer dígito de los 5 restantes de la parte izquierda, paridad par: 0 –> 0100111
  5. Segundo, paridad impar: 1 –> 0011001
  6. Tercero, paridad impar: 7 –> 0111011
  7. Cuarto, paridad par: 8 –> 0001001
  8. Quinto, paridad par: 0 –> 0100111
  9. Marca central: 01010
  10. Primer dígito de la parte derecha, solo tienen una paridad: 1 –> 1100110
  11. Segundo: 9 –> 1110100
  12. Tercero: 0 –> 1110010
  13. Cuarto: 7 –> 1000100
  14. Quinto: 3 –> 1000010
  15. Sexto (dígito de control): 7 –> 1000100
  16. Marca de final: 101

Y con esto ya tenemos el código para 4901780190737:

10100010110100111001100101110110001001010011101010110011011101001110010100010010000101000100101

Y aquí el código de barras en cuestión.

ean13

Ales, otro día más…


Interleaved 2 of 5

October 25th, 2006

Más códigos de barras. Esta vez toca el Interleaved 2 of 5, un pelín más difícil e interesante. Veamos qué se le ocurrió a la mente retorcida que lo creó.

Esta simbología se utiliza sobre todo para crear símbolos numéricos en la industria de la distribución y almacenamiento.

Se codifican números con una cantidad de dígitos par y se codifican en grupos de dos, y ahí viene porque se le llama “interleaved” (entrelazado) porque el primer dato numérico del par se lo codifica en las cinco barras negras mientras que el segundo dato numérico del par se lo codifica en las cinco barras blancas del símbolo para el par. Sí, suena raro, igual no lo he sabido explicar bien, pero lo mejor será ver un ejemplo, pero para ello tenemos que saber como codificar dígito.

Antes de ir con el ejemplo necesitamos la tabla de codificación y la codificación de las marcas de inicio y final:

Carácter Interleaved 2 of 5
0 NNWWN
1 WNNNW
2 WWNNN
3 WWNNN
4 NNWNW
5 WNWNN
6 NWWNN
7 NNNWW
8 WNNWN
9 NWNWN

Donde N significa barra fina y donde W significa barra gruesa.

  • Marca de Inicio: 1010
  • Marca Final: 1101

Como sois gente lista habreis observado que ya no aparecen ‘0’s ni ‘1’s, pero al final obtendermos un código como el del artículo anterior.
De modo que como ejemplo, vamos a codificar 123 (sí, otra vez tengo una galletita para vosotros, tiene un número de dígitos impar).

Como tiene un número de dígitos impar con ponerle un 0 delante, solucionado, así que tenemos 0123 para codificar.

Lo primero que tenemos que hacer es buscar los equivalentes interleaved para cada carácter:

  • 0: NNWWN
  • 1: WNNNW
  • 2: NWNNW
  • 3: WWNNN

Y preparamos cada par de dígitos intercalándolos:

  • 01: NWNNWNWNNW
  • 23: NWWWNNNNWN
  • Si os fijais, el primer par comienza con la primera N del ‘0′, luego le sigue la primera W del ‘1′, continúa con la segunda N del ‘0′ y después está la primera N del ‘1′, y así sigue intercalando el ‘0′ y el ‘1′.

    Hecho esto suponemos que el primer carácter del par es una barra negra, que el segundo es una barra blanca y así vamos alternando entre barra negra y blanca hasta el final. Y sabiendo, como ya he dicho antes que N es una barra fina y que W es una barra gruesa quedaría:

    • 01: NWNNWNWNNW –> 10010110110100
    • 23: NWWWNNNNWN –> 10011001010110

    de modo que solo nos queda concatenarlo y ponerle las marcas de inicio y de final, quedando:

    101010010110110100100110010101101101

    Si os fijais, esta vez no hay barras finas blancas entre los dígitos o los pares de dígitos, eso es porque esta simbología es una de las denominadas contínuas.

    0123_intl25

    Otro día, más…


    Code 39

    October 24th, 2006

    Para comenzar vamos con uno de los códigos de barras más sencillos de crear, la simbología Code 39.Esta simbología se basa casi en una sustitución directa de los carácteres siguiendo la siguiente tabla

    Carácter
    Code 39 Carácter Code 39
    0 101001101101 M 110110101001
    1 110100101011 N 101011010011
    2 101100101011 O 110101101001
    3 110110010101 P 101101101001
    4 101001101011 Q 101010110011
    5 110100110101 R 110101011001
    6 101100110101 S 101101011001
    7 101001011011 T 101011011001
    8 110100101101 U 110010101011
    9 101100101101 V 100110101011
    A 110101001011 W 110011010101
    B 101101001011 X 100101101011
    C 110110100101 Y 110010110101
    D 101011001011 Z 100110110101
    E 110101100101 - 100101011011
    F 101101100101 . 110010101101
    G 101010011011 ESPACIO 100110101101
    H 110101001101 $ 100100100101
    I 101101001101 / 100100101001
    J 101011001101 + 100101001001
    K 110101010011 % 101001001001
    L 101101010011 DELIMITADOR 100101101101

    Un símbolo Code 39 comienza y acaba por el DELIMITADOR, y cada carácter simplemente se sustituye por su equivalente Code 39 de la tabla de arriba dejando entre cada carácter una barra fina blanca (es decir, un 0).

    Prediquemos con el ejemplo.

    Vamos a codificar “ARF”.

    Para empezar el DELIMITADOR: 100101101101

    luego continuamos con la A: 110101001011
    seguimos con la R: 110101011001
    y después la F: 101101100101
    para acabar con el DELIMITADOR: 100101101101

    Hay que recordar que entre cada carácter, incluidos los delimitadores hay que poner una barra blanca fina. Los marcaré para que se vean:

    1001011011010110101001011011010101100101011011001010100101101101

    Así se codificaría ARF con Code 39

    ARF

    Otro día complicaré un poco más las cosas :P


    Códigos de Barras

    October 24th, 2006

    Hace unas semanas me pidieron que hiciera un programa para crear códigos de barras, de modo que me puse a buscar información sobre como se codifican y no me resultó fácil encontrarla, al menos no es español. Casi que lo único que encontraba eran empresas que intentaban venderte sus APIs para crearlos o sus aplicaciones, cosa que no me interesaba. De modo que aquí comienzo unos articulillos sobre los códigos de barras.

    Antes que nada un poco de nomenclatura (lo iré ampliando a medida que vaya recordando o necesitando explicar algún término):

    • Símbolo: Es la impresión física de un código de barras.
    • Simbología: Es cada uno de los códigos con los que se puede codificar una cadena.
    • Densidad: Es la anchura de la barra más fina del símbolo.

    Hay muchas simbologías con diferentes usos cada una de ellas, algunos ejemplos:

    • Code 39: Simbología alfanumérica usada en la industria capaz de codificar 44 carácteres.
    • Code 128: Simbología alfanumérica para la industria capaz de codificar 128 carácteres ASCII.
    • EAN-13: Simbología numérica utilizada en comercios detallistas, es el típico de los supermercados, las tiendas…
    • Interleaved 2 of 5: Simbología numérica utilizada en almacenes de alta densidad.

    Algunos convenios con los que trabajaré, las líneas blancas finas las repesentaré con un ‘0′, las líneas finas negras las representaré con un ‘1′. Cuando se trate de una línea más ancha símplemente duplicaré o triplicaré el 0 o el 1 según sea el caso. Por ejemplo, para códigos de doble densidad, es decir que las líneas anchas son dos veces más anchas que las finas simplemente duplicaré el carácter con el que represento la barra: 00 ó 11, pero hay códigos de densidad múltiple, que son códigos en los que hay varias anchuras diferentes dentro de un mismo símbolo.

    Dicho esto, comenzamos.