/// Collects statistics about the SKS packet dump using the openpgp
/// crate, Sequoia's low-level API.
///
/// Note that to achieve reasonable performance, you need to compile
/// Sequoia and this program with optimizations:
///
/// % cargo run -p sequoia-openpgp --example statistics --release \
/// -- <packet-dump>
use std::env;
use std::collections::HashMap;
extern crate sequoia_openpgp as openpgp;
use crate::openpgp::{Packet, Fingerprint, KeyID, KeyHandle};
use crate::openpgp::types::*;
use crate::openpgp::packet::{user_attribute, header::BodyLength, Tag};
use crate::openpgp::packet::signature::subpacket::SubpacketTag;
use crate::openpgp::parse::{Parse, PacketParserResult, PacketParser};
use crate::openpgp::serialize::MarshalInto;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
panic!("Collects statistics about OpenPGP packet dumps.\n\n\
Usage: {} <packet-dump> [<packet-dump>...]\n", args[0]);
}
// Global stats.
let mut packet_count = 0;
let mut packet_size = 0 as usize;
// Per-tag statistics.
let mut tags_count = vec![0; 64];
let mut tags_unknown = vec![0; 64];
let mut tags_size_bytes = vec![0 as usize; 64];
let mut tags_size_count = vec![0; 64];
let mut tags_size_min = vec![::std::u32::MAX; 64];
let mut tags_size_max = vec![0; 64];
// Signature statistics.
let mut sigs_count = vec![0; 256];
let mut sigs_count_1st_party = vec![0; 256];
// Signature Subpacket statistics.
let mut sigs_subpacket_tags_count = vec![0; 256];
let mut sigs_subpacket_tags_unknown = vec![0; 256];
let mut sigs_subpacket_tags_size_bytes = vec![0 as usize; 256];
let mut sigs_subpacket_tags_size_count = vec![0; 256];
let mut sigs_subpacket_tags_size_min = vec![::std::u32::MAX; 256];
let mut sigs_subpacket_tags_size_max = vec![0; 256];
let mut sigs_subpacket_exportable_true = 0;
let mut sigs_subpacket_exportable_false = 0;
let mut sigs_subpacket_re_zero_terminated = 0;
let mut sigs_subpacket_re_inner_zero = 0;
// Per-Signature statistics.
let mut signature_min = PerSignature::max();
let mut signature_max = PerSignature::min();
// Various SubpacketValue-related counters.
let mut key_flags: HashMap<KeyFlags, usize> = Default::default();
let mut p_sym: HashMap<Vec<SymmetricAlgorithm>, usize> =
Default::default();
let mut p_hashes: HashMap<Vec<HashAlgorithm>, usize> =
Default::default();
let mut p_comp: HashMap<Vec<CompressionAlgorithm>, usize> =
Default::default();
let mut p_aead: HashMap<Vec<AEADAlgorithm>, usize> =
Default::default();
// Per-Cert statistics.
let mut cert_count = 0;
let mut cert = PerCert::min();
let mut cert_min = PerCert::max();
let mut cert_max = PerCert::min();
// UserAttribute statistics.
let mut ua_image_count = vec![0; 256];
let mut ua_unknown_count = vec![0; 256];
let mut ua_invalid_count = 0;
// Current certificate.
let mut current_fingerprint =
KeyHandle::Fingerprint(Fingerprint::from_bytes(&vec![0; 20]));
let mut current_keyid = KeyHandle::KeyID(KeyID::wildcard());
// For each input file, create a parser.
for input in &args[1..] {
eprintln!("Parsing {}...", input);
let mut ppr = PacketParser::from_file(<