sábado, noviembre 25, 2006

Algoritmos y dígitos de control

Hoy tengo el día tonto y no quiero hablar de problemas sino de matemáticas, aunque en el fondo, ¿Qué son las matemáticas sin problemas y los problemas sin matemáticas?

Bueno. Pues me puse a destripar los dígitos de control de la referencia catastral que nos aparece en los recibos del IBI, antes contribución. (El destripado del digito de control del DNI se puede encontrar en Internet con lo que no tenía ninguna gracia dedicarle tiempo).

Con la ayuda de ovc.catastro.meh.es para consultar diferentes parcelas y ver los dígitos calculados he llegado al siguiente algoritmo:

Para el primer digito de control tómese las 7 primeras posiciones de la referencia catastral y el numero de cargo sobre 4 posiciones justificado a la derecha (p. ej. 0027).

Para el segundo digito, tómese la segunda parte de la referencia (posiciones 8 a 14) y las 4 posiciones del cargo.

Remplácese en su caso las letras por números según la siguiente conversión:

A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8, I=9, J=10, K=11, L=12, M=13, N=14, Ñ=15, O=16, P=17, Q=18, R=19, S=20, T=21, U=22, V=23, W=24, X=25, Y=26 y Z=27

Multipliquese cada digito (o en su caso el valor correspondiente de la letra) por los siguientes valores según su posición:

1º=13, 2º=15, 3º=12, 4º=5, 5º=4, 6º=17, 7º=9, 8º=21, 9º=3, 10º=7, 11º=1

Súmense todos los valores obtenidos y divídase por 23, obteniendo un resto (entre 0 y 22).

Conviertase dicho resto a letra según la siguiente tabla:

0 =M, 1 =Q, 2 =W, 3= E, 4 =R, 5= T, 6 =Y, 7= U, 8= I, 9= O, 10= P, 11= A, 12= S, 13= D, 14= F, 15= G, 16= H, 17= J, 18= K, 19= L, 20= B, 21= Z, 22= X
Y ya lo tenemos. Otro dia me entretendre con alguna otra curiosidad.

10 comentarios:

Anónimo dijo...

Hola,

Es muy interesante. Por mucho que he buscado este algoritmo no he visto ninguna descripción hasta ahora.

No entiendo cómo se calcula el primer dígito de control. Tengo las siguientes dudas:

* ¿Qué dígitos son los de número de cargo? (posiciones dentro de los 20 caracteres).
* ¿Cómo se calcula a partir de las 7 primeras posiciones de la referencia y las cuatro del número de cargo?

También ayudaría mucho si pudieras poner un ejemplo.

Gracias.

pepito grillo dijo...

- tema cargo:
el cargo son las 4 posiciones justo antes de los dígitos de control. las posi. son 15-16-17-18, la posi 19 y 20 son los d.c.

el cargo es un número secuencial que identifica recibos dentro de una finca

Anónimo dijo...

Si señor, mi enhorabuena !!! Pero hay un problema, cuando las referencias catastrales son rústicas, el algoritmo no sirve. ¿Sabría decirme que algoritmo utilizan las referencias catastrales no urbanas también llamadas rústicas?

Gracias, de nuevo mis felicitaciones.

Anónimo dijo...

Enhorabuena, el algoritmo me funciona perfectamente para calcular el primer carácter de control, sin duda porque solo usa dígitos numéricos; pero no consigo que me funcione cuando aparecen letras, es decir, para el cálculo del segundo carácter.

Analizando, por ejemplo, la referencia catastral 001500100UF97B0001QI, para el segundo carácter de control, tendríamos...

0 -> 0 * 13 = 0
0 -> 0 * 15 = 0
U -> 22 * 12 = 264
F -> 6 * 5 = 30
9 -> 9 * 4 = 36
7 -> 7 * 17 = 119
B -> 2 * 9 = 18

Sumando las cantidades, obtenemos 467.

El resto de dividir por 23 nos da 7.

El carácter que corresponde al 7, según la tabla de sustitución, es "U", pero en la referencia catastral figura "I".

Dado que con dígitos numéricos el algoritmo es correcto, el fallo puede estar en el reemplazo de letras por números.

Si hago algo mal, por favor, indícamelo pues me sería muy útil este algoritmo. Y si necesitas algunas referencias catastrales para cotejo, te las puedo hacer llegar.

Gracias

El autor dijo...

Efectivamente parece que hay algún problema con la segunda parte de la referencia y con las rústicas. Lo estudiaré.

El autor dijo...

Bueno. Solucionado el error. En negrita en el post lo que faltaba.

Anónimo dijo...

Ahora sí...

Enhorabuena y muchas gracias.

CHITO dijo...

A PARTIR DE LAS OPERACIONES SEÑALADAS POR EL AUTOR HE HECHO UNA HOJA DE CALCULO QUE ME SIRVE ADEMAS DE PARA CALCULAR LOS DIGITOS DE CONTROL DE UNA REFERENCIA CATASTRAL, TAMBIEN PARA CALCULAR A PARTIR DE LA DEL SOLAR LA DE TODOS LOS NUMEROS DE ORDEN DE LA FINCA CONSTRUIDA SOBRE EL SOLAR (DIVISION ADMINISTRATIVA). MUCHAS GRACIAS AL AUTOR

El autor dijo...

Pues un paso mas. Un programita en BASIC (si, el qbasic funciona en XP)


ON ERROR GOTO SIGUE
DIM valor(20)

CADENA$ = "MQWERTYUIOPASDFGHJKLBZX"
OPEN "entrada.txt" FOR INPUT AS #1
OPEN "salida.txt" FOR OUTPUT AS #2

DO WHILE NOT EOF(1)
INPUT #1, rec$
segmento$ = MID$(rec$, 1, 2)
r1$ = MID$(rec$, 3, 28)
parcela$ = MID$(rec$, 31, 18)
dc$ = MID$(rec$, 49, 2)
r2$ = MID$(rec$, 51, 950)
IF segmento$ = "15" OR segmento$ = "46" OR segmento$ = "49" OR segmento$ = "48" THEN GOSUB calcula

PRINT #2, segmento$; r1$; parcela$; dc$; r2$
LOOP
CLOSE #1
CLOSE #2
END


calcula:

FOR posicion = 1 TO 18

IF MID$(parcela$, posicion, 1) = "A" THEN valor(posicion) = 1
IF MID$(parcela$, posicion, 1) = "B" THEN valor(posicion) = 2
IF MID$(parcela$, posicion, 1) = "C" THEN valor(posicion) = 3
IF MID$(parcela$, posicion, 1) = "D" THEN valor(posicion) = 4
IF MID$(parcela$, posicion, 1) = "E" THEN valor(posicion) = 5
IF MID$(parcela$, posicion, 1) = "F" THEN valor(posicion) = 6
IF MID$(parcela$, posicion, 1) = "G" THEN valor(posicion) = 7
IF MID$(parcela$, posicion, 1) = "H" THEN valor(posicion) = 8
IF MID$(parcela$, posicion, 1) = "I" THEN valor(posicion) = 9
IF MID$(parcela$, posicion, 1) = "J" THEN valor(posicion) = 10
IF MID$(parcela$, posicion, 1) = "K" THEN valor(posicion) = 11
IF MID$(parcela$, posicion, 1) = "L" THEN valor(posicion) = 12
IF MID$(parcela$, posicion, 1) = "M" THEN valor(posicion) = 13
IF MID$(parcela$, posicion, 1) = "N" THEN valor(posicion) = 14
IF MID$(parcela$, posicion, 1) = "¥" THEN valor(posicion) = 15
IF MID$(parcela$, posicion, 1) = "O" THEN valor(posicion) = 16
IF MID$(parcela$, posicion, 1) = "P" THEN valor(posicion) = 17
IF MID$(parcela$, posicion, 1) = "Q" THEN valor(posicion) = 18
IF MID$(parcela$, posicion, 1) = "R" THEN valor(posicion) = 19
IF MID$(parcela$, posicion, 1) = "S" THEN valor(posicion) = 20
IF MID$(parcela$, posicion, 1) = "T" THEN valor(posicion) = 21
IF MID$(parcela$, posicion, 1) = "U" THEN valor(posicion) = 22
IF MID$(parcela$, posicion, 1) = "V" THEN valor(posicion) = 23
IF MID$(parcela$, posicion, 1) = "W" THEN valor(posicion) = 24
IF MID$(parcela$, posicion, 1) = "X" THEN valor(posicion) = 25
IF MID$(parcela$, posicion, 1) = "Y" THEN valor(posicion) = 26
IF MID$(parcela$, posicion, 1) = "Z" THEN valor(posicion) = 27
IF MID$(parcela$, posicion, 1) = "0" THEN valor(posicion) = 0
IF MID$(parcela$, posicion, 1) = "1" THEN valor(posicion) = 1
IF MID$(parcela$, posicion, 1) = "2" THEN valor(posicion) = 2
IF MID$(parcela$, posicion, 1) = "3" THEN valor(posicion) = 3
IF MID$(parcela$, posicion, 1) = "4" THEN valor(posicion) = 4
IF MID$(parcela$, posicion, 1) = "5" THEN valor(posicion) = 5
IF MID$(parcela$, posicion, 1) = "6" THEN valor(posicion) = 6
IF MID$(parcela$, posicion, 1) = "7" THEN valor(posicion) = 7
IF MID$(parcela$, posicion, 1) = "8" THEN valor(posicion) = 8
IF MID$(parcela$, posicion, 1) = "9" THEN valor(posicion) = 9
NEXT posicion

valor(1) = valor(1) * 13
valor(2) = valor(2) * 15
valor(3) = valor(3) * 12
valor(4) = valor(4) * 5
valor(5) = valor(5) * 4
valor(6) = valor(6) * 17
valor(7) = valor(7) * 9
valor(8) = valor(8) * 13
valor(9) = valor(9) * 15
valor(10) = valor(10) * 12
valor(11) = valor(11) * 5
valor(12) = valor(12) * 4
valor(13) = valor(13) * 17
valor(14) = valor(14) * 9
valor(15) = valor(15) * 21
valor(16) = valor(16) * 3
valor(17) = valor(17) * 7
valor(18) = valor(18) * 1
total1 = 0
total2 = 0

FOR X = 1 TO 7
total1 = total1 + valor(X)
total2 = total2 + valor(X + 7)
NEXT X

FOR X = 15 TO 18
total1 = total1 + valor(X)
total2 = total2 + valor(X)
NEXT X
PRINT total1, total2
resto1 = total1 - (FIX(total1 / 23) * 23)
resto2 = total2 - (FIX(total2 / 23) * 23)

dc1$ = MID$(CADENA$, resto1 + 1, 1)
dc2$ = MID$(CADENA$, resto2 + 1, 1)

dc$ = dc1$ + dc2$


RETURN

SIGUE:
RESUME NEXT

El autor dijo...

Evidentemente entrada es un FIN2006 sin los DC y salida es un FIN2006 con ellos.