ASN.1 utiliza alguns tipos primitivos (elementos de dados) com os quais podem ser compostas estruturas mais complexas. Os tipos primitivos ou básicos são:
Estruturas complexas são definidas agregando-se tais tipos primitivos de algumas formas previstas na ASN.1. As principais formas de estruturação de tipos compostos ou "construídos" são:
ASN.1 define uma notação para especificação de valores e para definição de tipos. A definição de um tipo consiste numa coleção de campos que, no mais baixo nível, consiste de um identificador, uma possível etiqueta (rótulo ou "tag"), uma referência e uma possível indicação de que aquele campo e opcional (pode ser omitido).
No menor nível os campos da definição são combinados usando mecanismos de estruturação que começa com o nome do tipo da estrutura e então, em geral, uma lista de campos separados por vírgulas e envolvidos em chaves "{}". É válido usar aninhamento de estruturas.
O identificador compreensível (letra minúscula) serve apenas para auxiliar a compreensão mas é ignorado pelas regras de codificação básicas.
O rótulo ("tag") permite que dois tipos aparentemente idênticos sejam separados tal que seu uso possa ser distinguido em construções tal como CHOICE ou SET.
Assim, um tipo será definido, segundo a ASN.1 usando-se uma das sequências de tipo válidas, que são:
Type::= BuiltinType|DefinedType BuiltinType::= BooleanType| IntegerType| BitStringType| OctetStringType| NullType| SequenceType| SequenceOfType| SetTypeType| SetOfType| ChoiceType| TaggedType| AnyType| CharacterSetType| UsefulType|
O DefinedType especifica sequências externas usadas para referir definições de tipos e valores.
Os mais significativos tipos de primitivos serão definidos a seguir:
DiasComSolNoMes::= BITSTRING{primeiro(1),ultimo(31)} -- Um dia foi ensolarado se o bit correspondente a ele no mapa tem valor 1
A segunda forma é preferível, quando possível.
IdentificaçãoPaciente ::= SEQUENCE { nome OCTET STRING, numeroQuarto CHOICE {INTEGER, NULL --se o paciente já saiu do hospital-- }}
NomeNaçõesMembros ::= SEQUENCE OF ISO646String -- na ordem em que se integraram
NomeDosFuncionarios ::= SEQUENCE {presidente ISO646String, vicePresidente ISO646String, secretaria ISU646String }
Também pode ser usado o tipo SEQUENCE quando o tipo dos integrantes difere, mas o número e conhecido e modesto e cuja ordem e significante, desde que a composição do conjunto dificilmente mude de uma versão do protocolo para outra. Exemplo:
Credenciais ::= SEQUENCE {nomeUsuario ISO646String, password ISO646String, numeroConta INTEGER }Se os elementos de uma sequência são em número fixo mas de vários tipos, um nome de referência deve ser atribuído a cada elemento cujo objetivo não seja completamente evidente de seu tipo. Exemplo:
Arquivo ::= SEQUENCE { TipoConteudo, outros AtributosArquivo, conteudo ANY }
NomeUsuario ::= SET { nomePessoal [0] IMPLICIT ISO646String, nomeOrganização [1] IMPLICIT ISO646String, nomePais [2] IMPLICIT ISO646String }
A palavra OPTIONAL pode ser colocada após uma variável do conjunto cujo aparecimento e opcional. Se os membros de um tipo SET são em número fixo, também deve ser atribuído um nome a cada membro cujo fim não e evidente de seu tipo. Exemplo:
AtributosArquivo ::= SET {proprietario [0] IMPLICIT NomeUsuario, tamanhoDoConteudoEmOctetos [1] IMPLICIT INTEGER, [2] IMPLICIT ControleAcesso }
Também podem ser usados tipos rotulados para definir um tipo de dados de uso amplo e disperso, num particular contexto de apresentação e que deve ser distinguível (por meio de sua representação) de todos os outros tipos de dados usados naquele contexto de apresentação. Exemplo:
NomeArquivo ::= [APPLICATION 8] IMPLICIT SEQUENCE { nomeDiretorio ISO646String, nomeRelativoArquivoDiretorio ISO646String }
Os rótulos específicos de um contexto são usados para distinguir os membros de um conjunto. Os rótulos numéricos devem começar de zero se sua única meta e distinguir os tipos. Exemplo:
RegistroCliente ::= SET {nome [0] IMPLICIT ISO646String, enderecoPostal [1] IMPLICIT ISO646String, numeroConta [2] IMPLICIT INTEGER, debito [3] IMPLICIT INTEGER --em centavos-- }Quando um particular membro do conjunto recebeu um rótulo a nível de
aplicação não necessita receber rótulo especifico de contexto.Ex:
RegistroProduto ::= SET { CodigoUniforme, descrição [0] IMPLICIT ISO646String, numeroEstoque [1] IMPLICIT INTEGER } CodigoUniforme ::= [APPLICATION 13] IMPLICIT INTEGER
Rotulação especifica de contexto também e usada para distinguir as alternativas de uma escolha (CHOICE). Rótulos numéricos começam em zero se seu único propósito e distinguir os diversos tipos. Exemplo:
AtributoDeCliente ::= CHOICE {nome [0] IMPLICIT ISO646String, enderecoPostal [1] IMPLICIT ISO646String, numeroDaConta [2] IMPLICIT INTEGER, debito [3] IMPLICIT INTEGER -- em centavos--}
Os rótulos de uso privativo são usados para rotular tipos de dados que são de uso apenas no escopo de uma particular organização ou pais e que devem ser distinguiveis de todos os demais tipos de dadso usados por aquela organização ou pais. Exemplo:
IdentificadorArquivo ::= CHOICE { nomeRelativo [0] IMPLICIT ISO646String, -- nome do arquivo nomeAbsoluto [1] IMPLICIT ISO646String, -- nome do arquivo e do diretorio que o contem< numeroSerial [2] IMPLICIT INTEGER --identificador atribuido pelo sistema }
O tipo seleção e usado para representar uma variável cujo tipo e um dentre alguma particular alternativa de um CHOICE previamente definido.
Exemplo: a definição seguinte é possível
AtributosCorrentes ::= SEQUENCE { data-ultimo-uso AtributoArquivo, nome-arquivo AtributoArquivo }se existir a seguinte definição:
AtributoArquivo ::= CHOICE { data-ultimo-uso INTEGER, nome-arquivo ISO646String }
ConteudoMensagem ::= ANY
-- um elemento de dados cujo tipo e especificado na norma XXX