Cómo obtener el Dígito de Control de un Número de Seguridad Social español
Por Enrique Martínez Montejo
Última revisión: 17/09/2010
 

La función genérica que aparece en esta página, le vendrá de perlas a todos aquellos programadores que desarrollen aplicaciones de nóminas y de seguros sociales, sobre todo si los usuarios de su aplicación van a presentar los seguros sociales, o los modelos de altas y bajas de los trabajadores, a través del programa Red de la Tesorería General de la Seguridad Social.

Aunque los nuevos números de Afiliación (NAF) constan de 12 dígitos, como bien podrá comprender, siguen existiendo infinidad de números antiguos (por ejemplo, sin ir más lejos, mi propio número de Seguridad Social), donde su longitud total no podía superar los 11 dígitos. Pero aparte de los números de Afiliación, también las empresas tienen sus correspondientes números de inscripción, más conocidos como Códigos de Cuenta de Cotización (CCC), y al igual que los números de Afiliación, también existen Códigos de Cuenta de Cotización nuevos (11 dígitos) y antiguos (10 dígitos de longitud).

Es por ello, y a fin de obtener el dígito de control verdadero, se necesite diferenciar entre un antiguo y un nuevo número de Seguridad Social, tanto si se trata de una persona física o afiliada, como de un particular o empresa que tengan trabajadores por cuenta ajena, por lo que necesariamente deberá de tener asignado un Código de Cuenta de Cotización, que le servirá de identificación ante la Administración de la Seguridad Social, para dar de alta y baja a sus propios trabajadores, así como para proceder a la liquidación mensual de los correspondientes boletines de cotización.

Todos los números de Seguridad Social (NAF y CCC) se componen de tres partes:

Número de Afiliación (NAF) Número de Código de Cuenta de Cotización
23 / 12345678 / 23 23 / 1234567 / 50

Los dos primeros dígitos (23) se corresponden con el código de la provincia que emite el número de Seguridad Social (en el ejemplo, sería la provincia de Jaén). Los siguientes ocho (12345678) y siete (1234567) números respectivos, es un número correlativo que automáticamente lo genera el sistema informático de la Administración de la Seguridad Social, cuando se produce la afiliación inicial de cualquier persona al Sistema de la Seguridad Social, o se inscribe por primera vez una empresa. Por último, los dos últimos dígitos (23 y 50), se corresponden con el dígito de control que valida al número expedido. Da la casualidad que en el ejemplo que he expuesto para el NAF, tanto el dígito provincial como el dígito de control coinciden, pero les aseguro que no tiene por qué ser así; habrá veces que coincidan y otras no.

Los números expuestos arriba, se corresponderían con uno de los nuevos números de Seguridad Social que se asignan en la actualidad, y la diferencia estriba en que los números correlativos (en el ejemplo, 12345678 y 1234567) comienzan por un número distinto de cero, por lo que el siguiente ejemplo se correspondería con números antiguos de Seguridad Social, debidamente formateados con ceros, para que se adapte a la nueva longitud de 12 y 11 caracteres respectivamente:

Número de Afiliación (NAF) Número de Código de Cuenta de Cotización
02 / 01234567 / 06 02 / 0123456 / 29

En este último ejemplo, los hipotéticos números de Seguridad Social, se corresponderían con antiguos números expedidos por la provincia de Albacete, la cual, su dígito provincial es 02. Esto muestra que para que el número resultante tenga 12 u 11 dígitos, siempre se debe de formatear las tres partes de la que consta el número de Seguridad Social: dígito provincial, número de secuencia correlativo y dígito de control.

Después de calentarme la cabeza con varias implementaciones, me he quedado con el resultado final de la función GetDCNumSegSocial que muestro en esta página, la cual, aparte de tener en cuenta todos los aspectos comentados anteriormente, tiene la ventaja que obtiene el dígito de control correcto, se pase o no formateado a la función, la parte correlativa del número, siempre y cuando la parte correspondiente al dígito provincial (23 ó 02), se encuentre debidamente formateada a dos dígitos, porque de lo contrario, se obtendrá el dígito de control correspondiente a otro número.

Ello es debido a que es la misma función la que se encarga de formatear el número, antes de utilizar el algoritmo de cálculo del dígito de control, por lo que podrá pasar el número a la función de alguna de las tres siguientes maneras:

Los tres números pasados, devolverán el dígito de control 85. He optado por esta solución, porque muchas veces, tanto el trabajador como el empresario, omiten los ceros correspondientes a la segunda parte del número (00123456), en los documentos presentados ante la Administración de la Seguridad Social, por lo que el usuario de nuestra aplicación, no tendrá que preocuparse de si tiene que formatear o no previamente el número.

Hago especial hincapié, que para un correcto cálculo del dígito de control, en la cadena numérica pasada al argumento de la función, deberá especificar formateado el dígito provincial para aquellas provincias cuyos números se encuentren comprendidos entre el 01 (Álava) y 09 (Burgos), dado que la función toma los dos primeros caracteres del argumento, para calcular el dígito provincial del número, por tanto si desea conocer el dígito de control de un número de Alicante (03), y se olvida de incluir el cero inicial, la función entenderá que desea obtener el dígito de control de un número que comienza entre 30 y 39.

Asimismo, la función asume por defecto que el número pasado es un Número de Afiliación (NAF). Si desea obtener el dígito de control de un Código de Cuenta de Cotización, deberá especificar el valor True, en el segundo argumento de la función.

Por último advertirle que, en caso de pasar una cadena superior a 10 caracteres, o que incluya un carácter alfabético, la función devolverá una excepción del tipo System.ArgumentException, por lo que le aconsejo incluir la llamada a la función, dentro de un bloque Try ... End Try, a fin de controlar la excepción producida.

''' <summary>
''' Devuelve el dígito de control de un Número de Afiliación como de
''' un Número de Cuenta de Cotización.

''' </summary>
''' <param name="numSegSocial">Número cuyo dígito de control se desea obtener.</param>
''' <param name="esNumEmpresa">Indica si el Número se corresponde con el de una Empresa.</param>
''' <returns></returns>
''' <remarks></remarks>
Public
Function GetDCNumSegSocial(ByVal numSegSocial As String, _
                                  ByVal isNumEmpresa As Boolean) As String

    ' Si hay más de 10 dígitos en el número se devolverá una excepción de
    ' argumentos no permitidos.
    '
   
If (numSegSocial.Length > 10) OrElse (numSegSocial.Length = 0) Then _
        Throw New System.ArgumentException()

    ' Si algún carácter no es un número, abandono la función.
    '

    Dim regex As New System.Text.RegularExpressions.Regex("[^0-9]")
    If (regex.IsMatch(numSegSocial)) Then _
        Throw New System.ArgumentException()

    Try
        ' Obtengo el número correspondiente a la Provincia
        '

        Dim dcProv As String = numSegSocial.Substring(0, 2)

        ' Obtengo el resto del número
        '

        Dim numero As String = numSegSocial.Substring(2, numSegSocial.Length - 2)

        Select Case numero.Length
            Case 8
                If (esNumEmpresa) Then
                    ' Si el número es de una empresa, no puede tener 8 dígitos.
                    Return String.Empty

                Else
                    ' Compruebo si es un NAF nuevo o antiguo.
                    If (numero.Chars(0) = "0"c) Then
                        ' Es un número de afiliación antiguo. Lo formateo
                        ' a siete dígitos, eliminando el primer cero.

                        numero = numero.Remove(0, 1)

                    End If

             
  End If

            Case 7
                ' Puede ser un NAF antiguo o un CCC nuevo o viejo.
                If (esNumEmpresa) Then
                    ' Si el primer dígito es un cero, es un CCC antiguo,
                    ' por lo que lo formateo a seis dígitos, eliminando
                    ' el primer cero.

                    If (numero.Chars(0) = "0"c) Then
                        numero = numero.Remove(0, 1)
                    End If
                End If

            Case 6
                ' Si se trata del número de una empresa,
                ' es un CCC antiguo.

                If (Not (esNumEmpresa)) Then
                    ' Es un NAF antiguo, por lo que lo debo
                    ' de formatear a 7 dígitos.

                    numero = numero.PadLeft(7, "0"c)
                End If

            Case Else
                ' Todos los demás casos, serán números antiguos
                If (esNumEmpresa) Then
                    ' Lo formateo a seis dígitos.
                    numero = numero.PadLeft(6, "0"c)

                Else
                    ' Lo formateo a siete dígitos.
                    numero = numero.PadLeft(7, "0"c)

                End If

        End Select

        ' Completo el número de Seguridad Social
        '

        Dim naf As Int64 = Convert.ToInt64(dcProv & numero)

        ' Calculo el Dígito de Control. Tengo que operar con números
        ' Long, para evitar el error de desbordamiento que se puede
        ' producir con los nuevos números de Seguridad Social
        '

        naf = naf - (naf \ 97) * 97

        ' Devuelvo el Dígito de Control formateado
        '

        Return String.Format("{0:00}", naf)

    Catch
        Return String.Empty

    End Try

End Function

 

Cómo obtener el Dígito de Control de un Número de Seguridad Social español

Si la función la incluye en alguna clase, sería conveniente que cambiara su ámbito a Private, y creara dos funciones independientes públicas, que llamaran a la función GetCDNumSegSocial: una para los NAF y otra para los CCC:

Public Function GetDCNumSegSocial(ByVal numSegSocial As String) As String
    ' Obtiene dígitos de control de números de Afiliación
    Return GetDCNumSegSocial(numSegSocial, False)
End Function

Public Function GetDCNumEmpresa(ByVal numSegSocial As String) As String
    ' Obtiene dígitos de control de números de Empresa
    Return GetDCNumSegSocial(numSegSocial, True)
End Function

 

Otros enlaces de interés:

Cómo validar un Número de Seguridad Social español (Afiliados y Empresas)

Indice de la Biblioteca de Funciones de Códigos de Control


Enrique Martínez Montejo - 2010

NOTA: La información contenida en este artículo, así como el código fuente incluido en el mismo, se proporciona COMO ESTÁ, sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo explicado, recomendado o sugerido en el presente artículo.

NOTE: The information contained in this article and source code included therein, is provided AS IS without warranty of any kind, and confers no rights. You assume any risk to implement, use or run it explained, recommended or suggested in this article.