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