2017-01-18 6 views
1

Hier ist eine verschachtelte Tupel von einer Erlang-Bibliothek:Get Wert von verschachtelten Tupel

tuple = {:Certificate, 
      {:TBSCertificate, 
      :v3, 
      3464270192823392628, 
      {:AlgorithmIdentifier, {1, 2, 840, 113549, 1, 1, 11}, <<5, 0>>}, 
      {:Validity, {:utcTime, '160428162930Z'}, {:utcTime, '170528162930Z'}}, 
      :asn1_NOVALUE, 
      :asn1_NOVALUE, 
      :asn1_NOVALUE, 
      :asn1_NOVALUE, 
      :asn1_NOVALUE}} 

Um die :Validity Tupel zu finden, muss ich

tuple |> elem(1) |> elem(4) 

ich ein Muster tun Anpassung kann tun, aber es gibt zu viel :asn1_NOVALUE im Ende ich möchte sie einfach ignorieren.

Gibt es in Erlang/Elixir einen anderen Weg, den verschachtelten Tupelwert zu erhalten? So etwas wie

get_in(tuple, [:Certificate, :Validity]) 
+1

Es sieht aus wie ein Erlang Datensatz, so dass Sie wahrscheinlich 'Record' Modul Elixir verwenden sollten, die einige Makros für einen einfachen Zugang zur Verfügung stellt :) – JustMichael

+0

Das Tupel-Ergebnis war von http://erlang.org/doc/man/public_key.html#pem_entry_decode-2, sah in "Record.extract/2", obwohl nach dem Lesen der Dokumentation immer noch nicht sicher, wie man das verwendet .. – sbs

+0

Welche Version von Erlang verwendest du? Ich wollte eine Antwort mit Record-Makros schreiben, aber es sieht so aus, als ob Erlang 19 vor AlgorithmIdentifier in TBSCertificate record ein zusätzliches Feld hat. – Dogbert

Antwort

1

Ich fand here die Definition des Datensatzes 'TBSCertificate':

'TBSCertificate'{ 
     version,    % v1 | v2 | v3 
     serialNumber,   % integer() 
     signature,   % #'AlgorithmIdentifier'{} 
     issuer,    % {rdnSequence, [#AttributeTypeAndValue'{}]} 
     validity,    % #'Validity'{} 
     subject,    % {rdnSequence, [#AttributeTypeAndValue'{}]} 
     subjectPublicKeyInfo, % #'SubjectPublicKeyInfo'{} 
     issuerUniqueID,  % binary() | asn1_novalue 
     subjectUniqueID,  % binary() | asn1_novalue 
     extensions   % [#'Extension'{}] 
    }. 

Es ist erlang Notation, aber ich denke, es wird mit Elixier gleichwertig sein. In erlang können Sie die Informationen 'Validity' mit der Rekord-Syntax abrufen:

{_,TBScert} = Tuple, 
Validity = Tuple#'TBSCertificate'.'Validity' % which is also a record 

Ich bin nicht vertraut mit Elixier der Syntax, ich denke, es so etwas wie

{_,tbs_cert} = tuple, 
validity = :TBSCertificate(tbs_cert, :Validity), 

Aber ich cant't es testen. Die Definition des 'Validity' Datensatz ist:

'Validity'{ 
     notBefore, % time() 
     notAfter % time() 
    }. 
0

Ich möchte etwas tun:

with {:Certificate, cert} <- tuple, 
    [_, _, _, _, {:Validity, v1, v2} | _] <- Tuple.to_list(cert), 
do: {v1, v2} 
%⇒ {{:utcTime, '160428162930Z'}, {:utcTime, '170528162930Z'}} 
1

Sie können von Aufzeichnungsinformationen extrahieren public_key.hrl

require Record 
Record.defrecord :certificate Record.extract(:Certificate, from_lib: "public_key/include/public_key.hrl") 
Record.defrecord :TBSCertificate Record.extract(:TBSCertificate, from_lib: "public_key/include/public_key.hrl") 
Record.defrecord :validity Record.extract(:Validity, from_lib: "public_key/include/public_key.hrl") 

Dann können Sie Muster Spiel schreiben

certificate(tbsCertificate: TBSCert) = Tuple, 
TBSCertificate(Validity: valid) = TBSCert, 
validity(notBefore: from, notAfter: to) = valid, 

Ich weiß Elixir nicht genug, um zu wissen, ob dies würde auch funktionieren

certificate(tbsCertificate: TBSCertificate(Validity: validity(notBefore: from, notAfter: to))) = Tuple,