How to differentiate phone types

20

I have the following problem: the client will send me a phone number and I need to differentiate if it is fixed or cell phone, does anyone know some rules that distinguish the two groups well?     

asked by anonymous 29.04.2014 / 22:01

7 answers

29

The Numbering Plan is the way to organization of the numbers of public use telecommunications services. The table below shows the relationship between the fixed and cellular numbers, based on which I think it is easy to solve your problem.

Source: Teleco

    
29.04.2014 / 23:17
23

Structure of the Brazilian Telephone System

Numbers can essentially have 4 servings:

Inaddition,thereareothernumberswithaspecialnomenclature,publicutilitynumbersthatcontainonly3digits.

Typesofnumbers

Thereareonlytwotypesofnumbers,fixedormobile,distinguishedbythefirstdigit:

  • 2to5arefixednumbers(landline)
  • 6to9aremobilenumbers(mobilephone)

Pseudocode

Basedontheabovedataexposed,thealgorithmwouldhavetoworkwithinthefollowingtemplates:

  • Verifythatyouhavemorethanthreedigitstodetermineifitisapublicutilitynumber.

    Ifitisofpublicuse,weendhereandactaccordingly.

  • Checkifnumberstartswith+55todetermineifithasthecountrycode.

    Ifyouhavethecountrycode,wewillremoveitfromthenumberandcontinuewiththeverification.

  • Verifythatyouhaveatleast12digits.

    Ifyoudonothave12ormoredigits,it'sinvalid,we'redonehereandweactaccordingly.

  • Verifythatyouhave13digits.

    Ifyouhave13digits,it'sSãoPaulo'smobilenumber,weendhereandweactaccordingly.

  • Checkwhetherfixedormobile.

    Arrivingherewehavetohave12digits,solet'stakethe5thdigitandcheckifitisinthegroup(2~5)orthegroup(6~9),wefinishtheoperationandactaccordingly.

    /p>

  • Optional:

    Splitthe12digitsintoportionstoidentifywhereitis:

    2dígitos-Operadora2dígitos-Áreageográfica4dígitos-Primeirapartedonúmero4dígitos-Segundapartedonúmero
  • Diagram

    Theflowofinformationbasedonwhatwehavelearnedsofarcanbepresentedasfollows:

    Code

    Putting this entire exercise into practice, let's implement the solution with JavaScript:

    document.getElementById("validar").onclick = function() {
    
      var continuar = true,
        numero = document.getElementById('numero').value;
    
      // Verificar se vazio
      if (numero.length === 0) {
        alert("Brincalhão, preenche lá o número!");
        continuar = false;
      }
    
      // Verificar se número é de utilidade publica
      if (numero.length === 3) {
        alert("Número de utilidade publica");
        continuar = false;
      }
    
      // Verificar se tem código do país para retirar
      if (continuar && numero.substring(0, 3) === "+55") {
        numero = numero.substring(3);
      }
    
      // Verificar se menos que 12 digitos
      if (continuar && numero.length < 12) {
        alert("Número inválido, por favor introduza Cod. Operadora + Cod. Area + Numero");
        continuar = false;
      }
    
      // Verificar se contém 13 digitos
      if (continuar && numero.length === 13) {
        alert("Número móvel");
        continuar = false;
      }
    
      // Verificar se o 5º digito
      var digitoControlo = numero.charAt(4);
    
      if (continuar) {
    
        if (digitoControlo >= 2 && digitoControlo <= 5) {
          alert("Número fixo");
        } else if (digitoControlo >= 6 && digitoControlo <= 9) {
          alert("Número móvel");
        } else {
          alert("Número especial");
        }
      }
    }
    <form>
      <input type="text" id="numero" name="numero" />
      <button id="validar">validar</button>
    </form>

    Notes:

    There are other checks to be performed, such as if there are no letters in place of numbers, but such checks are not part of the number count and should be taken into account before the number is started.

    Some of the checks can not even be requested, it goes from the implementation of each one, which is why they are separated, becoming modular.

    I am Portuguese from Portugal, if I have missed any details about the structure of your telephone system, leave a comment, I will be happy to update the answer.

        
    04.04.2015 / 07:59
    5

    Currently by anatel only the phone numbers that start with 6,7,8,9 are cell numbers. You can make a regex to interpret this . Remember that it is only the phone number not including ddd.

        
    29.04.2014 / 22:17
    3

    You can use Twillo's new Lookup service.

    link

    With the paid module it gives you the type of the number (mobile or fixed) and the operator also.

    curl -X GET https://lookups.twilio.com/v1/PhoneNumbers/55-11-5525-6325\
        -d "Type=carrier"
        -u "{AccountSid}:{AuthToken}"
    
    {
        "country_code": "BR",
        "phone_number": "+551155256325",
        "national_format": "(11) 5525-6325",
        "url": "https://lookups.twilio.com/v1/PhoneNumber/+551155256325",
        "carrier": {
            "type": "landline",
            "error_code": null,
            "mobile_network_code": null,
            "mobile_country_code": null,
            "name": "Vivo"
        }
    }
    
        
    08.04.2015 / 03:05
    3

    After studying the answer from Zuul and review this article from #, I adapted his solution (in JavaScript ) for the two main programming languages I use: Java and Object Pascal . Creating the respective classes. And the code has been tested and is working for numbers with and without the NON-DIGIT .

    However, I have made some changes to accept special numbers, such as 0300 , 0500 , 0800 , 0900 4003 , 4003 , and 4004 . I also fixed some bugs when the user informs numbers with more zeros, for example: (OP) 041 (DDD) 87 (NUM) 9999-9999 (PO) 41 (DDD) 087 (NUM) 9999-9999 .

    Below the class code.

    In Java :

    /*
            Telefone - Retorna o tipo de um número de telefone (fixo, móvel, público etc.)
    
            Baseado neste tópico:
    
            . https://pt.stackoverflow.com/questions/14343/como-diferenciar-tipos-de-telefone
    
            Autores:
    
            . Silvio Clécio - github.com/silvioprog
    */
    
    package br.com.duallsistemas.telefone;
    
    /**
     * Created by silvioprog on 06/04/2015.
     */
    public class Telefone {
        private String numero;
        private String ddd;
        private String codOperadora;
    
        public Telefone(String codOperadora, String ddd, String numero) {
            this.codOperadora = apenasNumeros(apenasString(codOperadora));
            this.ddd = apenasNumeros(apenasString(ddd));
            setNumero(numero);
        }
    
        public Telefone(String codOperadora, String ddd) {
            this(codOperadora, ddd, "");
        }
    
        public Telefone() {
            this("", "");
        }
    
        private boolean inRange(int num, int min, int max) {
            return num >= min && num <= max;
        }
    
        private boolean numeroEspecial() {
            return numero.startsWith("0300") || numero.startsWith("0500") || numero.startsWith("0800") ||
                    numero.startsWith("0900") || numero.startsWith("3003") || numero.startsWith("4003") ||
                    numero.startsWith("4004");
        }
    
        private boolean temNonoDigito() {
            Integer i = Integer.parseInt(numero.substring(0, 2));
            return inRange(i, 11, 19) || inRange(i, 21, 24) || i == 27 || i == 28 || inRange(i, 91, 99);
        }
    
        protected String apenasNumeros(String s) {
            if (s == null)
                return "";
            String result = "";
            for (char c : s.toCharArray()) {
                if (c >= '0' && c <= '9')
                    result += c;
            }
            return result;
        }
    
        protected String apenasString(String s) {
            if (s == null)
                return "";
            s = s.trim();
            if (s.equals(""))
                return "";
            return s;
        }
    
        public String getCodOperadora() {
            return codOperadora;
        }
    
        public String getDdd() {
            return ddd;
        }
    
        public TipoTelefone obtemTipo() {
            int len = numero.length();
            if (len <= 2)
                return TipoTelefone.INVALIDO;
            if (len == 3)
                return TipoTelefone.PUBLICO;
            if (len < 12) {
                if (numeroEspecial())
                    return TipoTelefone.ESPECIAL;
                else
                    return TipoTelefone.INVALIDO;
            }
            if (len == 13)
                return TipoTelefone.MOVEL;
            char digito;
            if (len == 15)
                digito = numero.charAt(7);
            else
                digito = numero.charAt(4);
            if (digito >= '2' && digito <= '5')
                return TipoTelefone.FIXO;
            if (digito >= '6' && digito <= '9')
                return TipoTelefone.MOVEL;
            return TipoTelefone.ESPECIAL;
        }
    
        public String getDescricao() {
            return String.valueOf(obtemTipo());
        }
    
        public String getNumero() {
            return numero;
        }
    
        public void setNumero(String numero) {
            numero = apenasString(numero);
            if (numero.equals(""))
                return;
            if (numero.startsWith("+55"))
                numero = numero.substring(3);
            this.numero = apenasNumeros(numero);
            int len = this.numero.length();
            if (len == 8 ) {
                if (!numeroEspecial())
                    this.numero = codOperadora + ddd + this.numero;
            } else if (len == 9)
                this.numero = codOperadora + ddd + this.numero;
            else if (len == 10)
                this.numero = codOperadora + this.numero;
            else if (len == 11 || len == 14) {
                if (!numeroEspecial() && this.numero.substring(0, 1).equals("0")) {
                    this.numero = this.numero.substring(1);
                    this.numero = codOperadora + this.numero;
                } else if (temNonoDigito())
                    this.numero = codOperadora + this.numero;
            }
        }
    }
    

    Example of use (Note: the numbers used in the example are fictitious):

    package br.com.duallsistemas;
    
    import br.com.duallsistemas.telefone.Telefone;
    
    public class Main {
    
        public static void imprime(Telefone tel, String numero) {
            tel.setNumero(numero);
            System.out.println("NUMERO REAL: " + tel.getNumero() + ", TIPO: " + tel.getDescricao());
        }
    
        public static void main(String[] args) {
            Telefone tel = new Telefone("41", "65");
            System.out.println("INTRODUZA O NUMERO DO SEGUINTE FORMATO: COD. OPERADORA + COD. AREA + NUMERO");
            System.out.println("=======");
            System.out.println();
            // inválidos
            imprime(tel, "12");
            imprime(tel, "+55 41 (99) 999-9999");
            System.out.println();
            // público
            imprime(tel, "190");
            System.out.println();
            // especial
            imprime(tel, "0300 313 4701");
            imprime(tel, "0500 313 4701");
            imprime(tel, "0800 729 0722");
            imprime(tel, "0900 313 4701");
            imprime(tel, "3003 3030");
            imprime(tel, "4003 3030");
            imprime(tel, "4004 3030");
            System.out.println();
            // fixo
            imprime(tel, "3549-5589");
            imprime(tel, "(87) 3549-5589");
            System.out.println();
            // movel
            imprime(tel, "9985-0997");
            imprime(tel, "(87) 9985-0997");
            imprime(tel, "31 (87) 9985-0997");
            imprime(tel, "+55 31 (87) 9985-0997");
            System.out.println();
            // movel SP
            imprime(tel, "9 9985-0997");
            imprime(tel, "(11) 9 9985-0997");
            imprime(tel, "31 (11) 9 9985-0997");
            imprime(tel, "031 (11) 9 9985-0997");
        }
    }
    

    In Object Pascal (compatible with Free Pascal 2.6.4 + and Delphi 7 + ):

    (*
    
      TTelefone - Retorna o tipo de um número de telefone (fixo, móvel, público etc.)
    
      Baseado neste tópico:
    
        . https://pt.stackoverflow.com/questions/14343/como-diferenciar-tipos-de-telefone
    
      Autores:
    
        . Silvio Clécio - github.com/silvioprog
    
    *)
    
    unit Telefone;
    
    {$IFDEF FPC}
    {$mode objfpc}{$H+}
    {$ENDIF}
    
    interface
    
    uses
      SysUtils;
    
    type
    
      { TTipoTelefone }
    
      TTipoTelefone = (ttInvalido, ttPublico, ttFixo, ttMovel, ttEspecial);
    
      { TTelefone }
    
      TTelefone = class(TObject)
      private
        FNumero: string;
        FDdd: string;
        FCodOperadora: string;
        function GetCodOperadora: string;
        function GetDdd: string;
        function GetDescricao: string;
        function GetTipo: TTipoTelefone;
        procedure SetNumero(ANumero: string);
        function TemNonoDigito: Boolean;
        function NumeroEspecial: Boolean;
      public
        constructor Create(const ACodOperadora, ADdd, ANumero: string); overload; virtual;
        constructor Create(const ACodOperadora, ADdd: string); overload; virtual;
        constructor Create; overload; virtual;
        function ApenasNumeros(const S: string): string;
        function ApenasString(const S: string): string;
        property CodOperadora: string read GetCodOperadora;
        property Ddd: string read GetDdd;
        property Numero: string read FNumero write SetNumero;
        property Descricao: string read GetDescricao;
        property Tipo: TTipoTelefone read GetTipo;
      end;
    
    const
      DESC_TELEFONE: array[TTipoTelefone] of string = (
        'INVALIDO', 'PUBLICO', 'FIXO', 'MOVEL', 'ESPECIAL'
        );
    
    implementation
    
    { TTelefone }
    
    constructor TTelefone.Create(const ACodOperadora, ADdd, ANumero: string);
    begin
      inherited Create;
      FCodOperadora := ApenasNumeros(ApenasString(ACodOperadora));
      FDdd := ApenasNumeros(ApenasString(ADdd));
      SetNumero(ANumero);
    end;
    
    constructor TTelefone.Create(const ACodOperadora, ADdd: string);
    begin
      Create(ACodOperadora, ADdd, '');
    end;
    
    constructor TTelefone.Create;
    begin
      Create('', '');
    end;
    
    function TTelefone.TemNonoDigito: Boolean;
    var
      I, E: Integer;
    begin
      Val(Copy(FNumero, 1, 2), I, E);
      Result := E = 0;
      if Result then
        case I of
          11..19, 21..24, 27, 28, 91..99: Result := True;
          else
            Result := False;
        end;
    end;
    
    function TTelefone.NumeroEspecial: Boolean;
    var
      N: ShortString;
    begin
      N := Copy(FNumero, 1, 4);
      Result := (N = '0300') or (N = '0500') or (N = '0800') or (N = '0900') or
        (N = '3003') or (N = '4003') or (N = '4004');
    end;
    
    function TTelefone.ApenasNumeros(const S: string): string;
    var
      C: Char;
    {$IFNDEF FPC}
      I: Integer;
    {$ENDIF}
    begin
      Result := '';
    {$IFDEF FPC}
      for C in S do
        if (C >= '0') and (C <= '9') then
          Result += C;
    {$ELSE}
      for I := 1 to Length(S) do
      begin
        C := S[I];
        if (C >= '0') and (C <= '9') then
          Result := Result + C;
      end;
    {$ENDIF}
    end;
    
    function TTelefone.ApenasString(const S: string): string;
    begin
      Result := Trim(S);
    end;
    
    function TTelefone.GetCodOperadora: string;
    begin
      Result := FCodOperadora;
    end;
    
    function TTelefone.GetDdd: string;
    begin
      Result := FDdd;
    end;
    
    function TTelefone.GetTipo: TTipoTelefone;
    var
      D: Byte;
      L
    {$IFNDEF FPC}
      , E
    {$ENDIF}
      : Integer;
    begin
      L := Length(FNumero);
    {$IFDEF FPC}
      if L <= 2 then
        Exit(ttInvalido);
      if L = 3 then
        Exit(ttPublico);
      if L < 12 then
      begin
        if NumeroEspecial then
          Exit(ttEspecial)
        else
          Exit(ttInvalido);
      end;
      if L = 13 then
        Exit(ttMovel);
      if L = 15 then
        Val(FNumero[8], D)
      else
        Val(FNumero[5], D);
      if (D >= 2) and (D <= 5) then
        Exit(ttFixo);
      if (D >= 6) and (D <= 9) then
        Exit(ttMovel);
      Result := ttEspecial;
    {$ELSE}
      if L <= 2 then
        Result := ttInvalido
      else if L = 3 then
        Result := ttPublico
      else if L < 12 then
      begin
        if NumeroEspecial then
          Result := ttEspecial
        else
          Result := ttInvalido;
      end
      else if L = 13 then
        Result := ttMovel
      else
      begin
        if L = 15 then
          Val(FNumero[8], D, E)
        else
          Val(FNumero[5], D, E);
        if (D >= 2) and (D <= 5) then
          Result := ttFixo
        else if (D >= 6) and (D <= 9) then
          Result := ttMovel
        else
          Result := ttEspecial;
      end;
    {$ENDIF}
    end;
    
    function TTelefone.GetDescricao: string;
    begin
      Result := DESC_TELEFONE[GetTipo];
    end;
    
    procedure TTelefone.SetNumero(ANumero: string);
    var
      L: Integer;
    begin
      ANumero := ApenasString(ANumero);
      if ANumero = '' then
        Exit;
      if Copy(ANumero, 1, 3) = '+55' then
        ANumero := Copy(ANumero, 4, MaxInt);
      FNumero := ApenasNumeros(ANumero);
      L := Length(FNumero);
      if L = 8 then
      begin
        if not NumeroEspecial then
          FNumero := FCodOperadora + FDdd + FNumero;
      end else if L = 9 then
        FNumero := FCodOperadora + FDdd + FNumero
      else if L = 10 then
        FNumero := FCodOperadora + FNumero
      else if (L = 11) or (L = 14) then
        if (not NumeroEspecial) and (Copy(FNumero, 1, 1) = '0') then
        begin
          Delete(FNumero, 1, 1);
          FNumero := FCodOperadora + FNumero;
        end
        else if TemNonoDigito then
          FNumero := FCodOperadora + FNumero;
    end;
    
    end.
    

    Example usage:

    program test;
    
    {$IFDEF FPC}
    {$mode objfpc}{$H+}
    {$ENDIF}
    
    uses
      Telefone;
    
      procedure imprime(tel: TTelefone; const num: string);
      begin
        tel.Numero := num;
        WriteLn('NUMERO REAL: ', tel.Numero, ', TIPO: ', tel.Descricao);
      end;
    
    var
      tel: TTelefone;
    begin
      tel := TTelefone.Create('41', '65');
      try
        WriteLn('INTRODUZA O NUMERO DO SEGUINTE FORMATO: COD. OPERADORA + COD. AREA + NUMERO');
        WriteLn('=======');
        WriteLn;
        // inválidos
        imprime(tel, '12');
        imprime(tel, '+55 41 (99) 999-9999');
        WriteLn;
        // público
        imprime(tel, '190');
        WriteLn;
        // especial
        imprime(tel, '0300 313 4701');
        imprime(tel, '0500 313 4701');
        imprime(tel, '0800 729 0722');
        imprime(tel, '0900 313 4701');
        imprime(tel, '3003 3030');
        imprime(tel, '4003 3030');
        imprime(tel, '4004 3030');
        WriteLn;
        // fixo
        imprime(tel, '3549-5589');
        imprime(tel, '(87) 3549-5589');
        imprime(tel, '31 (87) 3549-5589');
        WriteLn;
        // movel
        imprime(tel, '9985-0997');
        imprime(tel, '(87) 9985-0997');
        imprime(tel, '31 (87) 9985-0997');
        WriteLn;
        // movel SP
        imprime(tel, '9 9985-0997');
        imprime(tel, '(11) 9 9985-0997');
        imprime(tel, '31 (11) 9 9985-0997');
        imprime(tel, '031 (11) 9 9985-0997');
        imprime(tel, '+55 31 (11) 9 9985-0997');
        imprime(tel, '+55 031 (11) 9 9985-0997');
      finally
        tel.Free;
        ReadLn;
      end;
    end.
    

    This code works perfectly well in an application in production , I hope it will be useful for the other colleagues! =)

        
    09.04.2015 / 23:02
    1

    I do not know if your question is still in your head, but I have found a solution.

    I found a site, and it contains a list of Operators, DDD's and Range of Prefixes in each State, being SME and / or SMP. From what I've noticed, from time to time they release an update from this list, but I downloaded the complete ones, both SME and SME, and put them on a table. Below is the link where I downloaded these files. link

    After that, I did a simple logic in sql. I think it's easier to show than explain.

    DECLARE
             @Telefone  VARCHAR(12) = 'ddXXXXXXXX' --<-- COLOQUE O TELEFONE AQUI
            ,@DDD       VARCHAR(2)
            ,@Prefixo   VARCHAR(5)
            ,@Final     INT
    
            SET @DDD        = LEFT(@Telefone, 2)
            SET @Prefixo    = LEFT(RIGHT(@Telefone, 8), 4)
            SET @Final      = RIGHT(@Telefone, 4)
    
        SELECT 
             Telefone = CONVERT(VARCHAR, DDD) + CONVERT(VARCHAR, Prefixo) + CONVERT(VARCHAR, @Final)
            ,Nome
            ,DDD
            ,Prefixo
            ,Final = @Final
        FROM Operadora 
        WHERE DDD = @DDD
          AND Prefixo LIKE '%' + @Prefixo
          AND @Final BETWEEN Inicial AND Final
    

    I just switched the mailing field names to usable names in tables, but I think it was very intuitive.

    In this script, if it has some end result, it is because it is a cell phone and it will put the ninth digit case on the phone it does not come. If you do not bring any results at the end, the number is a fixed number.

        
    10.11.2015 / 17:16
    1

    I saw many answers, but after a few hours analyzing everything we have about Brazilian phones, I created a function to validate the phones, including:

    • Repeat Number Validation
    • Validation of number of characters (if it is 10 or 11 numbers, other than the characters that do not count)
    • Cell validation (9th digit) if the number is 11 digits
    • Validation of DDDs (seed valid DDDs) - Thanks @renatoargh
    • Validate if the number is the same phone or radio type (if the number starts between 2 and 5, or 7) - Valid only after 2017, if ANATEL does everything right

    ANATEL has not yet implemented everything, but when someone sees this and is already in 2017 or later (look I'm just talking to someone of the future haha), just delete the line that checks the year, which is referenced in the code. / p>

    See a working example: JsFiddle

    Also follow the Gist for anyone who wants to help improve the code or report errors: Gist

    Thanks also to @Leandro Curioso, as I based my code on yours.

        
    03.06.2016 / 17:20