diff options
| author | adamjanovsky | 2023-12-15 11:03:59 +0100 |
|---|---|---|
| committer | adamjanovsky | 2023-12-15 11:03:59 +0100 |
| commit | de14da2a60e06d4d5d4389262b0e29c7c09e1050 (patch) | |
| tree | 2bac33d535cf96290ca2bfbc17acbc1c68bc85e9 | |
| parent | c93a6cf84984e692f08f36ed9629d0c57a3330a2 (diff) | |
| download | sec-certs-de14da2a60e06d4d5d4389262b0e29c7c09e1050.tar.gz sec-certs-de14da2a60e06d4d5d4389262b0e29c7c09e1050.tar.zst sec-certs-de14da2a60e06d4d5d4389262b0e29c7c09e1050.zip | |
bump some analysis
| -rw-r--r-- | notebooks/cc/references.ipynb | 281 |
1 files changed, 196 insertions, 85 deletions
diff --git a/notebooks/cc/references.ipynb b/notebooks/cc/references.ipynb index ff05ea3d..e474d816 100644 --- a/notebooks/cc/references.ipynb +++ b/notebooks/cc/references.ipynb @@ -30,7 +30,6 @@ "from collections.abc import Iterable\n", "from pathlib import Path\n", "\n", - "import matplotlib\n", "import matplotlib.pyplot as plt\n", "import networkx as nx\n", "import networkx.algorithms.community as nx_comm\n", @@ -47,14 +46,7 @@ "\n", "%matplotlib inline\n", "\n", - "# LaTeX plotting\n", "# matplotlib.use(\"pgf\")\n", - "# plt.rcParams[\"pgf.texsystem\"] = \"pdflatex\"\n", - "# plt.rcParams[\"font.family\"] = \"serif\"\n", - "# plt.rcParams[\"text.usetex\"] = True\n", - "# plt.rcParams[\"pgf.rcfonts\"] = False\n", - "\n", - "\n", "sns.set_theme(style=\"white\")\n", "plt.rcParams[\"axes.linewidth\"] = 0.5\n", "plt.rcParams[\"legend.fontsize\"] = 6.5\n", @@ -68,7 +60,10 @@ "plt.rcParams[\"xtick.major.size\"] = 5\n", "plt.rcParams[\"xtick.major.width\"] = 0.5\n", "plt.rcParams[\"xtick.major.pad\"] = 0\n", - "\n", + "# plt.rcParams[\"pgf.texsystem\"] = \"pdflatex\"\n", + "# plt.rcParams[\"font.family\"] = \"serif\"\n", + "# plt.rcParams[\"text.usetex\"] = True\n", + "# plt.rcParams[\"pgf.rcfonts\"] = False\n", "plt.rcParams[\"axes.titlesize\"] = 8\n", "plt.rcParams[\"legend.handletextpad\"] = 0.3\n", "plt.rcParams[\"lines.markersize\"] = 4\n", @@ -81,12 +76,9 @@ "\n", "# plt.rcParams['figure.figsize'] = (10, 6)\n", "\n", - "REPO_ROOT = Path().resolve()\n", "RESULTS_DIR = Path(\"./results/references\")\n", "RESULTS_DIR.mkdir(exist_ok=True, parents=True)\n", - "SMARTCARD_CATEGORY = \"ICs, Smart Cards and Smart Card-Related Devices and Systems\"\n", - "DATASET_PATH = REPO_ROOT / \"dataset/cc_november_23/dataset.json\"\n", - "PREDICTIONS_PATH = REPO_ROOT / \"dataset/reference_prediction/predictions.csv\"\n" + "SMARTCARD_CATEGORY = \"ICs, Smart Cards and Smart Card-Related Devices and Systems\"" ] }, { @@ -185,7 +177,7 @@ " target=\"reference\",\n", " create_using=nx.DiGraph,\n", " edge_attr=[\"reference_label\"],\n", - " )\n" + " )" ] }, { @@ -201,9 +193,9 @@ "metadata": {}, "outputs": [], "source": [ - "dset = CCDataset.from_json(DATASET_PATH)\n", + "dset = CCDataset.from_json(\"/var/tmp/xjanovsk/certs/sec-certs/dataset/cc_november_23/dataset.json\")\n", "cc_df = preprocess_cc_df(dset.to_pandas())\n", - "refs_df = preprocess_refs_df(PREDICTIONS_PATH, cc_df)\n", + "refs_df = preprocess_refs_df(\"/var/tmp/xjanovsk/certs/sec-certs/dataset/reference_prediction/predictions.csv\", cc_df)\n", "unique_labels = refs_df.reference_label.unique().tolist()\n", "\n", "# Load labeled reference graph as networkx directed graph\n", @@ -218,7 +210,7 @@ "cc_df = compute_reference_numbers(compute_references(cc_df, graph, unique_labels))\n", "cc_df_comp = compute_reference_numbers(compute_references(cc_df, graph, \"COMPONENT_USED\"))\n", "cc_df_prev = compute_reference_numbers(compute_references(cc_df, graph, \"PREVIOUS_VERSION\"))\n", - "assert cc_df.n_refs.sum() == cc_df_comp.n_refs.sum() + cc_df_prev.n_refs.sum()\n" + "assert cc_df.n_refs.sum() == cc_df_comp.n_refs.sum() + cc_df_prev.n_refs.sum()" ] }, { @@ -229,6 +221,22 @@ ] }, { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Display EAL in time\n", + "sec_levels = cc_df.loc[cc_df.year_from < 2023].groupby([\"year_from\", \"eal\"], as_index=False).size()\n", + "plt.figure()\n", + "g = sns.relplot(data=sec_levels, x=\"year_from\", y=\"size\", col=\"eal\", kind=\"line\", col_wrap=7)\n", + "g.set(xlabel=\"Year of certification\", ylabel=\"Number of issued certificates\")\n", + "g.fig.suptitle(\"Security level prevalence in time\", y=1.03)\n", + "g.fig.savefig(RESULTS_DIR / \"sec_levels_in_time.pdf\", bbox_inches=\"tight\")\n", + "g.fig.show()" + ] + }, + { "attachments": {}, "cell_type": "markdown", "metadata": {}, @@ -277,16 +285,15 @@ "\n", " df_melted = df[[\"n_refs\", \"n_trans_refs\", \"n_in_refs\", \"n_in_trans_refs\"]].melt()\n", " df_melted[\"incoming\"] = df_melted.variable.map(lambda x: bool(x.endswith(\"by\")))\n", + " plt.figure()\n", " g = sns.catplot(data=df_melted, kind=\"boxen\", x=\"variable\", y=\"value\", col=\"variable\", sharex=False, sharey=False)\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"boxen_plot_references.pdf\", bbox_inches=\"tight\")\n", - "\n", - " plt.show()\n", + " g.fig.savefig(RESULTS_DIR / \"boxen_plot_references.pdf\", bbox_inches=\"tight\")\n", + " g.fig.show()\n", "\n", " return {}\n", "\n", "\n", - "compute_basic_reference_graph_stats(cc_df, cc_df_comp, cc_df_prev)\n" + "compute_basic_reference_graph_stats(cc_df, cc_df_comp, cc_df_prev)" ] }, { @@ -334,16 +341,16 @@ " .melt(id_vars=\"date\", var_name=\"certificate\", value_name=\"reach\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_reach_evolution_melted, x=\"date\", y=\"reach\", hue=\"certificate\")\n", " g.set(title=\"Reach of top-10 certificates in time\", xlabel=\"Time\", ylabel=\"Certificate reach\")\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lineplot_top_certificate_reach.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lineplot_top_certificate_reach.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", " return top_10_certs.index.tolist()\n", "\n", "\n", - "top_10_digests = compute_certs_top_reach(cc_df_comp)\n" + "top_10_digests = compute_certs_top_reach(cc_df_comp)" ] }, { @@ -393,11 +400,11 @@ " .melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"n_references\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_avg_num_refs_melted, x=\"date\", y=\"n_references\", hue=\"category\")\n", " g.set(title=\"Average number of references in certificates\", xlabel=\"Time\", ylabel=\"Number of references\")\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lineplot_avg_n_references.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lineplot_avg_n_references.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", " return {}\n", "\n", @@ -421,21 +428,21 @@ " .melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"n_references\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_avg_num_refs_melted, x=\"date\", y=\"n_references\", hue=\"category\")\n", " g.set(\n", " title=\"Average certificate reach over time\",\n", " xlabel=\"Time\",\n", " ylabel=\"Number of (transitively) referencing certificates\",\n", " )\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lineplot_avg_reach.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lineplot_avg_n_references.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", " return {}\n", "\n", "\n", "compute_avg_references_over_time(cc_df_comp)\n", - "compute_avg_reach_over_time(cc_df_comp)\n" + "compute_avg_reach_over_time(cc_df_comp)" ] }, { @@ -487,15 +494,15 @@ " .melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"number of certificates\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_active_vs_ref_rich_melted, x=\"date\", y=\"number of certificates\", hue=\"category\")\n", " g.set(\n", " title=\"Number of active certificates vs. reference-rich certificates in time\",\n", " xlabel=\"Time\",\n", " ylabel=\"Number of certificates\",\n", " )\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lienplot_n_active_certs_vs_n_references.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lienplot_n_active_certs_vs_n_references.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", " return {}\n", "\n", "\n", @@ -532,6 +539,8 @@ " df_summary_references_melted = df_summary_references.melt(\n", " id_vars=[\"date\"], var_name=\"category\", value_name=\"number of certificates\"\n", " )\n", + "\n", + " plt.figure()\n", " g = sns.lineplot(\n", " data=df_summary_references_melted, x=\"date\", y=\"number of certificates\", hue=\"category\", errorbar=None\n", " )\n", @@ -540,9 +549,8 @@ " xlabel=\"Time\",\n", " ylabel=\"Number of certificates\",\n", " )\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lineplot_references_summary.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lineplot_references_summary.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", " df_ratios = df_summary_references.copy()\n", " df_ratios[\"ref. rich certificates\"] = df_ratios[\"ref. rich certificates\"] / df_ratios[\"active certificates\"]\n", @@ -551,20 +559,21 @@ " df_ratios = df_ratios.drop(columns=[\"active certificates\"])\n", " df_ratios_melted = df_ratios.melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"ratio of certificates\")\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_ratios_melted, x=\"date\", y=\"ratio of certificates\", hue=\"category\", errorbar=None)\n", " g.set(\n", " title=\"ratio of reference-rich vs. referenced vs. isolated certificates in time\",\n", " xlabel=\"Time\",\n", " ylabel=\"Number of certificates\",\n", " )\n", - " plt.savefig(RESULTS_DIR / \"lineplot_reference_ratio.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lineplot_reference_ratio.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", " return {}\n", "\n", "\n", "compute_number_of_active_vs_ref_rich_certs_over_time(cc_df_comp)\n", - "compute_summary_active_vs_ref_rich_over_time(cc_df_comp)\n" + "compute_summary_active_vs_ref_rich_over_time(cc_df_comp)" ] }, { @@ -629,20 +638,79 @@ " .melt(id_vars=[\"date\"], var_name=\"reference type\", value_name=\"number of certificates\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_refs_to_archived_melted, x=\"date\", y=\"number of certificates\", hue=\"reference type\")\n", " g.set(\n", " title=\"Number of active certificates that reference some archived certificate\",\n", " xlabel=\"Time\",\n", " ylabel=\"Number of certificates\",\n", " )\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lienplot_active_certs_referencing_archived.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lienplot_active_certs_referencing_archived.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", " return {}\n", "\n", "\n", - "compute_certs_referencing_archived_ones(cc_df_comp)\n" + "compute_certs_referencing_archived_ones(cc_df_comp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Certificates referencing an archived certificate on their issuance day" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_refs_to_archived_on_issuance_day(cc_df_comp: pd.DataFrame, cc_dset: CCDataset) -> None:\n", + " cert_id_to_dgst = {x.heuristics.cert_id: x.dgst for x in cc_dset}\n", + "\n", + " def cert_was_archived_on_date(date: pd.Timestamp, cert_id: str) -> bool:\n", + " if not date:\n", + " return False\n", + " if not dset[cert_id_to_dgst[cert_id]].not_valid_after:\n", + " return False\n", + " return date.date() > dset[cert_id_to_dgst[cert_id]].not_valid_after\n", + "\n", + " df__ = cc_df_comp.copy()\n", + " date_range = pd.date_range(df__.not_valid_before.min(), df__.not_valid_before.max())\n", + "\n", + " df_problematic = pd.DataFrame()\n", + " for date in tqdm(date_range):\n", + " certs_issued = df__.loc[(date == df__.not_valid_before) & (df__.n_refs > 0)].assign(\n", + " refs_to_archived_certs=lambda df_: df_.refs.map(\n", + " lambda refs: {x for x in refs if cert_was_archived_on_date(date, x)}\n", + " )\n", + " )\n", + " df_problematic = pd.concat(\n", + " [df_problematic, certs_issued[certs_issued.refs_to_archived_certs.map(lambda x: len(x) > 0)]]\n", + " )\n", + "\n", + " df_problematic = df_problematic[\n", + " [\n", + " \"cert_id\",\n", + " \"name\",\n", + " \"status\",\n", + " \"category\",\n", + " \"manufacturer\",\n", + " \"scheme\",\n", + " \"eal\",\n", + " \"not_valid_before\",\n", + " \"not_valid_after\",\n", + " \"cert_lab\",\n", + " \"refs\",\n", + " \"refs_to_archived_certs\",\n", + " ]\n", + " ]\n", + " df_problematic.to_csv(RESULTS_DIR / \"certs_with_refs_to_archived_on_their_issuance_date.csv\", sep=\";\", index=False)\n", + "\n", + "\n", + "compute_refs_to_archived_on_issuance_day(cc_df_comp, dset)" ] }, { @@ -704,19 +772,77 @@ " .melt(id_vars=[\"date\"], var_name=\"reference type\", value_name=\"number of certificates\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_references_vuln_melted, x=\"date\", y=\"number of certificates\", hue=\"reference type\")\n", " g.set(\n", " title=\"Number of active certificates that reference some vulnerable certificate\",\n", " xlabel=\"Time\",\n", " ylabel=\"Number of certificates\",\n", " )\n", - " fig = g.get_figure()\n", - " fig.savefig(RESULTS_DIR / \"lienplot_active_certs_referencing_vulnerable.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lienplot_active_certs_referencing_vulnerable.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", " return {}\n", "\n", "\n", - "compute_certs_referencing_vulnerable_over_time(cc_df_comp)\n" + "compute_certs_referencing_vulnerable_over_time(cc_df_comp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Certificates with sub-component reference to lower EAL cert" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_references_to_weaker_eals(cc_df_comp: pd.DataFrame, cc_dset: CCDataset) -> None:\n", + " eal_to_rank = {category: index for index, category in enumerate(cc_df_comp.eal.dtype.categories)}\n", + " cert_id_to_dst_mapping = {x.heuristics.cert_id: x.dgst for x in dset}\n", + "\n", + " def ref_is_weaker(cert_id: str, eal: str, ref_cert_id: str) -> bool:\n", + " eal_rank = eal_to_rank[eal]\n", + " ref_eal = dset[cert_id_to_dst_mapping[ref_cert_id]].eal\n", + " ref_eal_rank = eal_to_rank[ref_eal]\n", + " return ref_eal_rank < eal_rank\n", + "\n", + " df_ = cc_df_comp.copy()\n", + " df_ = (\n", + " df_.loc[\n", + " (df_.n_refs > 0) & (df_.eal.notnull()),\n", + " [\n", + " \"cert_id\",\n", + " \"name\",\n", + " \"status\",\n", + " \"category\",\n", + " \"manufacturer\",\n", + " \"scheme\",\n", + " \"eal\",\n", + " \"not_valid_before\",\n", + " \"not_valid_after\",\n", + " \"refs\",\n", + " ],\n", + " ]\n", + " .assign(\n", + " refs=lambda df__: df__.apply(\n", + " lambda row: {x for x in row.refs if ref_is_weaker(row.cert_id, row.eal, x)}, axis=1\n", + " ),\n", + " n_refs=lambda df__: df__.refs.map(len_if_exists),\n", + " referenced_levels=lambda df__: df__.refs.map(\n", + " lambda x: {dset[cert_id_to_dst_mapping[y]].eal for y in x} if pd.notnull(x) else set()\n", + " ),\n", + " )\n", + " .loc[lambda df__: df__.n_refs > 0]\n", + " )\n", + "\n", + " df_.to_csv(RESULTS_DIR / \"certs_referencing_weaker_eals.csv\", index=False, sep=\";\")\n", + "\n", + "\n", + "compute_references_to_weaker_eals(cc_df_comp, dset)" ] }, { @@ -760,7 +886,7 @@ "\n", "\n", "plot_direct_refs_per_category(cc_df_comp)\n", - "plot_direct_refs_per_category(cc_df_prev)\n" + "plot_direct_refs_per_category(cc_df_prev)" ] }, { @@ -787,6 +913,8 @@ " exploded[\"ref_category\"] = exploded.refs.map(lambda x: cert_id_to_category_mapping[x] if pd.notnull(x) else np.nan)\n", " exploded = exploded.loc[exploded.ref_category.notnull()]\n", "\n", + " exploded_with_refs = exploded.loc[exploded.ref_category != \"No references\"]\n", + "\n", " all_categories = set(exploded.category.unique()) | set(exploded.ref_category.unique())\n", " colors = list(sns.color_palette(\"hls\", len(all_categories), as_cmap=False).as_hex())\n", " color_dict = dict(zip(all_categories, colors))\n", @@ -795,6 +923,7 @@ " figure.set_size_inches(24, 10)\n", " figure.set_tight_layout(True)\n", "\n", + " plt.figure()\n", " sankey(\n", " exploded.category,\n", " exploded.ref_category,\n", @@ -805,13 +934,12 @@ " ax=axes,\n", " )\n", "\n", - " # plt.show()\n", - " plt.savefig(RESULTS_DIR / \"sankey_references_categories.pdf\", bbox_inches=\"tight\")\n", + " plt.show()\n", "\n", " return {}\n", "\n", "\n", - "plot_sankey_refs_categories(cc_df_comp)\n" + "plot_sankey_refs_categories(cc_df_comp)" ] }, { @@ -833,6 +961,7 @@ " has_outgoing_direct_references=lambda df_: df_.n_refs > 0,\n", " has_incoming_direct_references=lambda df_: df_.n_in_refs > 0,\n", " )\n", + " plt.figure()\n", " figure, axes = plt.subplots(1, 2)\n", " figure.set_size_inches(14, 4)\n", " figure.set_tight_layout(True)\n", @@ -854,7 +983,7 @@ " return {}\n", "\n", "\n", - "plot_refs_per_scheme(cc_df)\n" + "plot_refs_per_scheme(cc_df)" ] }, { @@ -893,6 +1022,7 @@ "\n", " col_to_depict = [\"category\", \"scheme\"]\n", "\n", + " plt.figure()\n", " figure, axes = plt.subplots(1, 2)\n", " figure.set_size_inches(14, 8)\n", " figure.set_tight_layout(True)\n", @@ -912,7 +1042,7 @@ " return {}\n", "\n", "\n", - "compute_certs_referencing_archived_ones(cc_df_comp)\n" + "compute_certs_referencing_archived_ones(cc_df_comp)" ] }, { @@ -943,6 +1073,7 @@ " colors = list(sns.color_palette(\"hls\", len(all_schemes), as_cmap=False).as_hex())\n", " color_dict = dict(zip(all_schemes, colors))\n", "\n", + " plt.figure()\n", " figure, axes = plt.subplots(1, 1)\n", " figure.set_size_inches(4, 4)\n", " figure.set_tight_layout(True)\n", @@ -964,28 +1095,7 @@ " return {}\n", "\n", "\n", - "plot_sankey_refs_schemes(cc_df)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Assurance mismatch\n", - "\n", - "- Search for certificates that use stronger EAL than the references subcomponent\n", - "- Examine cycles in the subcomponent graph" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# TBA\n", - "# Create a function that takes two arguments: cc_dset, eal, and references, and returns whether the cert. references something with lower EAL\n", - "# Just compute this boolean column for all certs\n" + "plot_sankey_refs_schemes(cc_df)" ] }, { @@ -1036,21 +1146,22 @@ " .melt(id_vars=[\"date\"], var_name=\"reference type\", value_name=\"number of certificates\")\n", " )\n", "\n", + " plt.figure()\n", " g = sns.lineplot(data=df_references_melted, x=\"date\", y=\"number of certificates\", hue=\"reference type\")\n", " g.set(\n", " title=\"Sum of references in currently active certs. with different labels in time\",\n", " xlabel=\"Time\",\n", " ylabel=\"Number of references\",\n", " )\n", - " plt.savefig(RESULTS_DIR / \"lineplot_different_labels.pdf\", bbox_inches=\"tight\")\n", - " plt.show()\n", + " g.figure.savefig(RESULTS_DIR / \"lineplot_different_labels.pdf\", bbox_inches=\"tight\")\n", + " g.figure.show()\n", "\n", "\n", "plot_ref_label_popularity_over_time(cc_df, cc_df_comp, cc_df_prev)\n", "\n", "print(\n", " f\"Number of certificates that did undergo re-evaluation (or previous version): {len(set(itertools.chain.from_iterable(cc_df_prev.loc[cc_df_prev.refs.notnull()].refs.tolist())))}\"\n", - ")\n" + ")" ] }, { @@ -1096,7 +1207,7 @@ " break\n", "else:\n", " raise ValueError(f\"Certificate with id {cert_id} not found in dataset.\")\n", - "print(f\" - its page is at https://seccerts.org/cc/{cert.dgst}/\")\n" + "print(f\" - its page is at https://seccerts.org/cc/{cert.dgst}/\")" ] }, { @@ -1105,7 +1216,7 @@ "metadata": {}, "outputs": [], "source": [ - "nx.draw(view, with_labels=True)\n" + "nx.draw(view, with_labels=True)" ] }, { @@ -1169,7 +1280,7 @@ "\n", "for com in communities:\n", " for i in sorted(com):\n", - " print(f\"\\t{i}\")\n" + " print(f\"\\t{i}\")" ] }, { @@ -1221,7 +1332,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.13" + "version": "3.11.6" }, "vscode": { "interpreter": { |
