فهرست مقاله
۱. فشردهسازیِ نشانیها، با حفظِ دقیقِ همان مجموعه

هنگامِ بازبینیِ فهرستِ نشانیهای مجاز، کوتاهتر شدنِ متن بهتنهایی نشانهٔ درستبودنِ تغییر نیست. اگر چند سطر را با یک پیشوندِ بزرگ جایگزین کنیم، ممکن است نشانیهایی واردِ مجموعه شوند که در ورودی نبودند. در این درس مسئله را محدود میکنیم: همان مجموعهٔ عددیِ IPv4 را با بلوکهای کمتری نمایش دهیم؛ نه عضوی کم شود و نه عضوی اضافه.
این محاسبه میتواند پیش از بررسیِ یک پیکربندی مفید باشد، اما فایلِ Nginx را نمیخواند و تغییر نمیدهد. ورودی فقط رشتههای شبکه با معنای یکسان است. نه اتصال، سوکت یا درخواستِ واقعی داریم و نه از خروجی، مجاز بودنِ یک کاربر یا درستیِ سیاستِ دسترسی را نتیجه میگیریم. کمیتِ موردِ شمارش، تعدادِ نشانیهاست؛ زمان، سرعت و تعدادِ میزبانهای فعال اندازهگیری نمیشوند.
مستنداتِ ipaddress در پایتون شبکه را با نشانی و ماسک معرفی میکند و برای collapse_addresses، تکرارگری از شبکههای ادغامشده برمیگرداند. ما خروجیِ آن را در یک دامنهٔ کوچک با مرجعِ مستقل میسنجیم. تابعِ supernet نیز شبکهٔ بزرگتر میسازد، اما بزرگتر بودنِ ظرف، برابریِ محتوای آن با چند شبکهٔ دلخواه را ثابت نمیکند.
دامنهٔ آموزشی، شانزده جایگاهِ عددی از 192.0.2.0 تا 192.0.2.15 است؛ یعنی شبکهٔ 192.0.2.0/28. از این نشانیها برای تماس با دستگاهی استفاده نمیکنیم. پیشوندهای پذیرفتهشده از /28 تا /32 هستند و تمامِ بلوک باید داخلِ همین محدوده باشد. این محدودیت برای خوانایی و بررسیِ متناهیِ خودمان انتخاب شده، نه محدودیتِ کتابخانه یا توصیهٔ طراحیِ شبکه.
۲. دو شبکهٔ همسایه همیشه یک شبکهٔ دقیق نمیسازند

برای شاهدِ دستی، 192.0.2.0/30 و 192.0.2.8/30 را بگیرید. اولی چهار عضوِ صفر تا سه و دومی چهار عضوِ هشت تا یازده دارد؛ اتحاد، هشت عضو است. شبکهٔ /28 شانزده عضو دارد و جایگاههای چهار تا هفت و دوازده تا پانزده را هم وارد میکند. پس یک سطر به جای دو سطر، در این نمونه نمایشِ معادل نیست.
در مقابل، دو بلوکِ 192.0.2.0/31 و 192.0.2.2/31 دقیقاً دو نیمهٔ همترازِ 192.0.2.0/30 هستند و میتوانند بدون افزودنِ عضو یکی شوند. همجواری لازم است، ولی همترازیِ بلوکِ توانی نیز اهمیت دارد. مثلاً دو تکنشانیِ یک و دو با وجودِ فاصلهٔ کم، یک /31 مشترکِ دقیق نمیسازند؛ مرزِ آن بلوکها روی جفتهای صفرـیک و دوـسه قرار دارد.
همپوشانی هم باید با اتحاد سنجیده شود. اگر /30 همراهِ یک /32 داخلِ خودش یا حتی همراهِ تکرارِ همان /30 بیاید، شمارِ اعضا بیشتر نمیشود. اینجا فراوانیِ مشاهده یا وزنِ هر سطر نداریم. حذفِ تکرار، از دست دادنِ یک اندازهگیری نیست؛ دادهٔ ورودی فقط نمایشِ چندبارهٔ عضویت است.
نشانیِ شبکه و broadcast را از مجموعه کم نمیکنیم. مستندات، پیمایشِ تمامِ نشانیها را از hosts جدا میکند؛ دومی قراردادِ میزبانهای قابلِ استفاده دارد. در مسئلهٔ ما /31 دو عضو و /32 یک عضو دارد. این نتیجه دربارهٔ فعال بودن، قابلِ مسیریابی بودن یا وضعیتِ واقعیِ هیچکدام خبری نمیدهد.
۳. ورودیِ معیار و مرزِ allowهای هممعنا

رابطِ تألیفی فقط tuple واقعیِ حداکثر شانزده رشته میگیرد. رشته باید str دقیق، ASCII، دارای پیشوندِ صریح و برابر با نمایشِ معیارِ کتابخانه باشد. شبکهٔ دارای بیتِ میزبان، ماسکِ نقطهای، فاصله، صفرِ اضافی در پیشوند، IPv6 و شبکهٔ بیرون از محدوده رد میشوند. اینها انتخابهای بازبینیِ ما هستند؛ کتابخانه بعضی نمایشهای دیگری را هم پشتیبانی میکند.
تمامِ ورودی پیش از فراخوانیِ تکرارگرِ ادغام بررسی میشود. بنابراین یک عضوِ نامعتبرِ انتهای فهرست، به نتیجهٔ موفقِ ناقص تبدیل نمیشود. منظور این نیست که هیچ سازندهای قبلاً اجرا نشده؛ ساخت و بررسیِ شبکههای قبلی بخشی از اعتبارسنجی بوده است. ادعای ایمنیِ عمومی برای ورودیِ نامطمئن یا محدودیتِ منابعِ تمامِ برنامه نیز نداریم.
راهنمای رسمیِ ماژولِ access در Nginx میگوید قواعد بهترتیب تا نخستین تطبیق بررسی میشوند. مثالِ مستندات یک نشانی را پیش از اجازهٔ شبکهٔ بزرگتر منع میکند؛ وراثتِ قواعد نیز شرطِ جدا دارد. پس نمیتوان همهٔ پیشوندهای یک فایلِ آمیختهٔ allow و deny را بیبرچسب جمع کرد و آن را بهینهسازیِ سیاست نامید.
کدِ حاضر نه دستورها را تحلیل میکند، نه ترتیبشان را عوض میکند و نه پیکربندیِ مؤثر پس از وراثت را میسازد. فقط نمایشِ یک مجموعهٔ هممعنا را برمیگرداند. اعتماد به نشانیِ مشتری، هدرهای پراکسی، محلِ اعمالِ تصمیم و احراز هویت مسئلههای دیگریاند. پیش از استقرارِ واقعی، حفظِ همین مجموعه تنها یکی از بررسیهای لازم خواهد بود.
۴. کد، پوششِ کمینه و مرجعِ مستقلِ صحیح

مسیرِ اصلی از IPv4Network با strict=True و سپس collapse_addresses استفاده میکند و خروجی را صریحاً بر حسبِ عددِ نشانی و طولِ پیشوند مرتب میکند. خروجی شاملِ رشتههای تغییرناپذیر، تعدادِ نشانیهای پوشش و شمارِ سطرهای ورودی است. کمکردنِ سطرها، ترتیبِ قراردادی و برابریِ اعضا سه ویژگیِ جدا هستند؛ هیچ پیکربندیِ اجرایی تولید نمیشود.
"""Authored bounded IPv4 set-cover review; no server, config, socket or traffic."""
import ipaddress
from itertools import permutations
import json
import platform
import sys
LAB = ipaddress.IPv4Network("192.0.2.0/28")
MAX_ENTRIES = 16
def _admit(values):
if type(values) is not tuple or len(values) > MAX_ENTRIES:
raise ValueError("exact tuple with at most16 entries required")
networks = []
for text in values:
if type(text) is not str or not text.isascii() or not 9 <= len(text) <= 18:
raise ValueError("exact canonical ASCII IPv4/prefix string required")
if text.count("/") != 1:
raise ValueError("explicit prefix required")
network = ipaddress.IPv4Network(text, strict=True)
if str(network) != text:
raise ValueError("canonical prefix-length spelling required")
if not 28 <= network.prefixlen <= 32 or not network.subnet_of(LAB):
raise ValueError("only the authored sixteen-position lab domain is accepted")
networks.append(network)
return tuple(networks)
def collapse_exact(values):
"""Canonical same-action set union; never a mixed ordered allow/deny policy."""
networks = _admit(values)
# The entire supplied tuple has been validated before the collapse call.
result = tuple(sorted(ipaddress.collapse_addresses(networks),
key=lambda n: (int(n.network_address), n.prefixlen)))
return {"networks": tuple(str(n) for n in result),
"covered_addresses": sum(n.num_addresses for n in result),
"input_entries": len(values),
"distinct_input_networks": len(set(str(n) for n in networks))}
def _manual_integer(text):
"""Oracle only: valid dotted-decimal input, no ipaddress helper."""
total = 0
for octet in text.split("."):
total = 256 * total + int(octet)
return total
def _manual_mask(valid_values):
base = _manual_integer("192.0.2.0")
mask = 0
for text in valid_values:
address, prefix = text.split("/")
low = _manual_integer(address) - base
width = 2 ** (32 - int(prefix))
for position in range(low, low + width):
mask |= 1 << position
return mask
def _minimum_cover_table():
"""Independent integer DP over exact membership sets, not sibling merging.
Every candidate is an aligned interval wholly within remaining membership.
The first remaining member must be in the next disjoint interval. Smaller
remaining masks have already been solved. Objective: count, then pair tuple.
No ipaddress, collapse_exact, _admit or library network object is used here.
"""
table = [()]
for membership in range(1, 1 << 16):
first = next(i for i in range(16) if membership & (1 << i))
candidates = []
for power in range(5):
width = 2 ** power
if first % width or first + width > 16:
continue
interval = ((1 << width) - 1) << first
if membership & interval == interval:
remainder = membership ^ interval
candidates.append(((first, 32 - power),) + table[remainder])
table.append(min(candidates, key=lambda value: (len(value), value)))
return table
def _integer_reference(valid_values, table):
"""Expected path only for valid materialized strings, not a second validator."""
membership = _manual_mask(valid_values)
pairs = table[membership]
return {"networks": tuple("192.0.2." + str(low) + "/" + str(prefix)
for low, prefix in pairs),
"covered_addresses": membership.bit_count(),
"input_entries": len(valid_values),
"distinct_input_networks": len(set(valid_values))}
def _rejects(values):
try:
collapse_exact(values)
except ValueError:
return True
return False
def run_example():
checks = {}
siblings = ("192.0.2.0/31", "192.0.2.2/31")
merged = collapse_exact(siblings)
checks["manual_aligned_siblings_merge_without_added_members"] = (
merged["networks"] == ("192.0.2.0/30",)
and merged["covered_addresses"] == 4
and _manual_mask(siblings) == _manual_mask(merged["networks"]) == 15)
holes = ("192.0.2.0/30", "192.0.2.8/30")
hole_result = collapse_exact(holes)
broad = str(ipaddress.IPv4Network(holes[0]).supernet(new_prefix=28))
additions = _manual_mask((broad,)) & ~_manual_mask(holes)
checks["one_broad_supernet_is_not_the_same_union_with_holes"] = (
hole_result["networks"] == holes and hole_result["covered_addresses"] == 8
and broad == "192.0.2.0/28" and additions.bit_count() == 8
and collapse_exact(("192.0.2.1/32", "192.0.2.2/32"))["networks"]
== ("192.0.2.1/32", "192.0.2.2/32"))
redundant = ("192.0.2.0/30", "192.0.2.0/30", "192.0.2.1/32")
redundancy = collapse_exact(redundant)
checks["duplicate_and_contained_networks_do_not_multiply_membership"] = (
redundancy == {"networks": ("192.0.2.0/30",), "covered_addresses": 4,
"input_entries": 3, "distinct_input_networks": 2})
quarters = tuple("192.0.2." + str(i) + "/30" for i in (0, 4, 8, 12))
checks["recursive_four_child_collapse_to_exact_parent"] = (
collapse_exact(quarters)["networks"] == ("192.0.2.0/28",)
and collapse_exact(quarters)["covered_addresses"] == 16)
pair = collapse_exact(("192.0.2.14/31",))
single = collapse_exact(("192.0.2.15/32",))
checks["numeric_endpoints_and_slash31_slash32_not_usable_host_filter"] = (
pair["covered_addresses"] == 2 and single["covered_addresses"] == 1
and _manual_mask(pair["networks"]) == (1 << 14) | (1 << 15)
and collapse_exact(("192.0.2.0/30",))["covered_addresses"] == 4)
hosts = tuple("192.0.2." + str(i) + "/32" for i in range(16))
checks["empty_input_and_inclusive_sixteen_entry_cap"] = (
collapse_exact(()) == {"networks": (), "covered_addresses": 0,
"input_entries": 0, "distinct_input_networks": 0}
and collapse_exact(hosts)["networks"] == ("192.0.2.0/28",)
and _rejects(hosts + (hosts[0],)))
arranged = ("192.0.2.12/31", "192.0.2.0/31", "192.0.2.2/31", "192.0.2.8/32")
ordered = collapse_exact(arranged)
permutation_cases = 0
for values in permutations(arranged):
assert collapse_exact(values) == ordered
permutation_cases += 1
checks["canonical_numeric_order_is_independent_of_input_permutation"] = (
permutation_cases == 24 and ordered["networks"]
== ("192.0.2.0/30", "192.0.2.8/32", "192.0.2.12/31"))
again = collapse_exact(ordered["networks"])
masks = [_manual_mask((text,)) for text in ordered["networks"]]
disjoint = all(not left & right for i, left in enumerate(masks) for right in masks[i + 1:])
ordered["networks"] = ("local-report-mutation",)
fresh = collapse_exact(arranged)
checks["idempotent_disjoint_cover_and_fresh_report_identity"] = (
again["networks"] == fresh["networks"] and disjoint
and again["covered_addresses"] == fresh["covered_addresses"] == 7
and fresh is not ordered and type(fresh["networks"]) is tuple)
valid_prefix_cases = 0
for prefix in range(28, 33):
width = 2 ** (32 - prefix)
for low in range(0, 16, width):
text = "192.0.2." + str(low) + "/" + str(prefix)
result = collapse_exact((text,))
assert result["networks"] == (text,) and result["covered_addresses"] == width
assert _manual_mask(result["networks"]) >> 16 == 0
valid_prefix_cases += 1
checks["all_thirty_one_admissible_lab_networks_preserve_their_domain"] = valid_prefix_cases == 31
class SubTuple(tuple):
pass
class SubString(str):
pass
consumed = []
def offered():
consumed.append(True)
yield "192.0.2.0/28"
bad_types = [[], "192.0.2.0/28", SubTuple(hosts),
(True,), (1,), (b"192.0.2.0/28",), (SubString("192.0.2.0/28"),),
(None,), offered()]
checks["exact_materialized_types_and_unconsumed_generator"] = (
all(_rejects(x) for x in bad_types) and consumed == [])
bad_spellings = ("192.0.2.1/28", "192.0.2.0/028", "192.0.2.0/255.255.255.240",
"192.0.2.0", "192.0.2.00/32", "192.0.2.16/28", "192.0.2.0/27",
"192.0.2.0/33", "192.0.2.0/-1", " 192.0.2.0/28", "192.0.2.0/28 ",
"::/128", "192.0.2.0/\u06f2\u06f8", "192.0.3.0/28", "0.0.0.0/0",
"192.0.2.0/29x", "192.0.2.256/32", "1/32")
checks["strict_canonical_host_bits_mask_family_and_lab_bounds"] = all(
_rejects((text,)) for text in bad_spellings)
original_collapse = ipaddress.collapse_addresses
collapse_calls = []
def spy(networks):
collapse_calls.append(tuple(str(n) for n in networks))
return original_collapse(networks)
ipaddress.collapse_addresses = spy
try:
late_invalid = _rejects(("192.0.2.0/30", "192.0.2.4/30", "192.0.2.9/30"))
invalid_did_not_call_collapse = collapse_calls == []
after_validation = collapse_exact(("192.0.2.4/30", "192.0.2.0/30"))
finally:
ipaddress.collapse_addresses = original_collapse
checks["whole_batch_validation_precedes_collapse_iterator_invocation"] = (
late_invalid and invalid_did_not_call_collapse and len(collapse_calls) == 1
and after_validation["networks"] == ("192.0.2.0/29",)
and ipaddress.collapse_addresses is original_collapse)
split_cases = 0
for power in range(1, 5):
width = 2 ** power
for low in range(0, 16, width):
parent = ("192.0.2." + str(low) + "/" + str(32 - power),)
children = tuple("192.0.2." + str(start) + "/" + str(33 - power)
for start in (low, low + width // 2))
assert collapse_exact(parent)["networks"] == collapse_exact(children)["networks"]
split_cases += 1
checks["fifteen_parent_to_two_child_representations_preserve_cover"] = split_cases == 15
table = _minimum_cover_table()
oracle_profiles = 0
maximum_cover_blocks = 0
for membership in range(1 << 16):
values = tuple(hosts[i] for i in range(16) if membership & (1 << i))
actual = collapse_exact(values)
expected = _integer_reference(values, table)
assert actual == expected, (membership, actual, expected)
assert _manual_mask(actual["networks"]) == membership
maximum_cover_blocks = max(maximum_cover_blocks, len(actual["networks"]))
oracle_profiles += 1
checks["independent_integer_minimum_cover_all_singleton_subsets_ONE_family"] = (
oracle_profiles == 65536 and len(table) == 65536)
assert len(checks) == 14 and all(type(value) is bool and value for value in checks.values()), checks
return {"python": platform.python_version(), "implementation": platform.python_implementation(),
"dependencies": "Python standard library only", "lab_network": str(LAB),
"input_entry_cap": MAX_ENTRIES, "prefix_minimum": 28, "prefix_maximum": 32,
"units": "numeric IPv4 addresses and input/output entries, not usable/active hosts or time",
"manual_siblings": {"input": siblings, "result": merged},
"manual_holes": {"input": holes, "result": hole_result, "overbroad_parent": broad,
"parent_extra_addresses": additions.bit_count()},
"redundant_input": redundancy,
"canonical_order_example": fresh,
"finite_cases_inside_groups": {"singleton_subsets_ONE_family": oracle_profiles,
"maximum_minimum_cover_blocks_in_family": maximum_cover_blocks,
"input_permutations": permutation_cases, "all_valid_lab_networks": valid_prefix_cases,
"parent_child_representations": split_cases,
"invalid_types": len(bad_types), "invalid_spellings_and_domains": len(bad_spellings)},
"checks": checks, "all_passed": True, "unique_check_groups": len(checks),
"nginx_executed": False, "network_or_configuration_changed": False,
"limits": ["Exact tuple/canonical IPv4 lab contract only, not general library validation",
"Set union has no action labels or first-match/inheritance semantics",
"Finite singleton-subset oracle family is not a global IPv4 correctness proof",
"Numeric coverage does not establish reachable hosts, trusted identity or access enforcement",
"No Nginx/socket/server/security-completeness/performance or deployment test"]}
if __name__ == "__main__":
sys.stdout.buffer.write((json.dumps(run_example(), ensure_ascii=True, indent=2) + "\n").encode("ascii"))
مرجع، سازنده یا تابعِ ادغامِ ipaddress را صدا نمیزند. بخشهای دهدهی را به عدد تبدیل میکند و شانزده جایگاه را در یک ماسکِ صحیح نگه میدارد. سپس تمامِ بازههای همترازِ با طولِ توانی را که کاملاً در مجموعهاند نامزد میکند. برنامهریزیِ پویا برای نخستین جایگاهِ باقیمانده، پوششی با کمترین تعدادِ بلوک میسازد؛ تساوی با ترتیبِ صریحِ زوجِ شروع و پیشوند شکسته میشود.
در خانوادهٔ محدود، تمامِ ۶۵۵۳۶ زیرمجموعهٔ شانزده تکنشانی بررسی میشوند و فقط یک گروهِ نامدارند. سیزده گروهِ دیگر، شاهدهای دستی، حفره، تکرار، همپوشانی، ترتیب، تداومِ نمایش، مرزِ نوع و اعتبارسنجی را در بر میگیرند؛ مجموع چهارده است. کمینگیِ این پوشش با مرجعِ تألیفی در دامنهٔ تعریفشده سنجیده میشود، نه با ادعای یک قضیهٔ مستندشده برای همهٔ ورودیهای کتابخانه.
گزارشِ زیر از اجرای واقعیِ فایل با CPython 3.14.5 و کتابخانهٔ استاندارد ثبت میشود. نسخهٔ صفحهٔ مرجع 3.14.9 است و با محیطِ اجرا یکی فرض نمیشود. آزمایش، بنچمارک نیست؛ از مدتِ اجرا یا کمشدنِ طولِ فهرست، سرعتِ بهترِ سرور نتیجه نمیگیریم. نمونههای مقالههای checksum و زمینهٔ IPv4 و مرزبندیِ پیام روی جریان TCP نیز قراردادهای آفلاینِ لایههای دیگریاند.
{
"python": "3.14.5",
"implementation": "CPython",
"dependencies": "Python standard library only",
"lab_network": "192.0.2.0/28",
"input_entry_cap": 16,
"prefix_minimum": 28,
"prefix_maximum": 32,
"units": "numeric IPv4 addresses and input/output entries, not usable/active hosts or time",
"manual_siblings": {
"input": [
"192.0.2.0/31",
"192.0.2.2/31"
],
"result": {
"networks": [
"192.0.2.0/30"
],
"covered_addresses": 4,
"input_entries": 2,
"distinct_input_networks": 2
}
},
"manual_holes": {
"input": [
"192.0.2.0/30",
"192.0.2.8/30"
],
"result": {
"networks": [
"192.0.2.0/30",
"192.0.2.8/30"
],
"covered_addresses": 8,
"input_entries": 2,
"distinct_input_networks": 2
},
"overbroad_parent": "192.0.2.0/28",
"parent_extra_addresses": 8
},
"redundant_input": {
"networks": [
"192.0.2.0/30"
],
"covered_addresses": 4,
"input_entries": 3,
"distinct_input_networks": 2
},
"canonical_order_example": {
"networks": [
"192.0.2.0/30",
"192.0.2.8/32",
"192.0.2.12/31"
],
"covered_addresses": 7,
"input_entries": 4,
"distinct_input_networks": 4
},
"finite_cases_inside_groups": {
"singleton_subsets_ONE_family": 65536,
"maximum_minimum_cover_blocks_in_family": 8,
"input_permutations": 24,
"all_valid_lab_networks": 31,
"parent_child_representations": 15,
"invalid_types": 9,
"invalid_spellings_and_domains": 18
},
"checks": {
"manual_aligned_siblings_merge_without_added_members": true,
"one_broad_supernet_is_not_the_same_union_with_holes": true,
"duplicate_and_contained_networks_do_not_multiply_membership": true,
"recursive_four_child_collapse_to_exact_parent": true,
"numeric_endpoints_and_slash31_slash32_not_usable_host_filter": true,
"empty_input_and_inclusive_sixteen_entry_cap": true,
"canonical_numeric_order_is_independent_of_input_permutation": true,
"idempotent_disjoint_cover_and_fresh_report_identity": true,
"all_thirty_one_admissible_lab_networks_preserve_their_domain": true,
"exact_materialized_types_and_unconsumed_generator": true,
"strict_canonical_host_bits_mask_family_and_lab_bounds": true,
"whole_batch_validation_precedes_collapse_iterator_invocation": true,
"fifteen_parent_to_two_child_representations_preserve_cover": true,
"independent_integer_minimum_cover_all_singleton_subsets_ONE_family": true
},
"all_passed": true,
"unique_check_groups": 14,
"nginx_executed": false,
"network_or_configuration_changed": false,
"limits": [
"Exact tuple/canonical IPv4 lab contract only, not general library validation",
"Set union has no action labels or first-match/inheritance semantics",
"Finite singleton-subset oracle family is not a global IPv4 correctness proof",
"Numeric coverage does not establish reachable hosts, trusted identity or access enforcement",
"No Nginx/socket/server/security-completeness/performance or deployment test"
]
}
۵. چهار پرسش دربارهٔ حفره، همپوشانی و سیاستِ واقعی

پرسش اول: چرا دو /30 جدا را همیشه با /28 جایگزین نکنیم؟ پاسخ: چون ظرفِ بزرگتر ممکن است عضوِ تازه اضافه کند. در شاهدِ صفر تا سه و هشت تا یازده، اتحاد هشت نشانی دارد ولی /28 شانزده نشانی. حفظِ تعدادِ بلوکها هدفِ اصلی نیست؛ حفظِ دقیقِ اعضا شرطِ مسئله است.
پرسش دوم: آیا broadcast و نشانیِ آغاز را حذف کنیم تا فهرستِ مجاز درست شود؟ پاسخ: در این مدل خیر؛ واحدِ بررسی، مجموعهٔ عددیِ شبکه است. فهرستِ میزبانهای قابلِ استفاده و سیاستِ پذیرشِ درخواست جدا تعریف میشوند. تعویضِ بیدلیلِ پیمایش با hosts میتواند خودِ مسئله را عوض کند.
پرسش سوم: اگر یک شبکه دوبار آمده باشد، آیا پوشش دو برابر است؟ پاسخ: خیر؛ اتحاد multiplicity ندارد. خروجی شمارِ سطرهای ورودی را برای مشاهده نگه میدارد، اما هر نشانی را یکبار میشمارد. اگر سطرها وزن، اولویت یا اقدامهای متفاوت داشته باشند، دیگر ورودیِ همین قرارداد نیستند.
پرسش چهارم: آیا موفقیتِ چهارده گروه برای تغییرِ هر فهرستِ Nginx کافی است؟ پاسخ: خیر؛ ترتیبِ نخستینتطبیق، وراثت، تشخیصِ مبدأ و اجرای واقعی بررسی نشدهاند. منابع در ۳۰ مهر ۱۴۰۵ خوانده شدند و تاریخِ انتشارِ نخستِ صفحات معلوم نبود. این متن آموزشِ پایه و بازبینیِ یک نمایشِ محدود است؛ نه خبر، گزارشِ استقرار یا تأییدِ کاملِ امنیت.
منابع و مطالعهٔ بیشتر
- Python3.14.9؛ شبکهٔ IPv4، شمارِ نشانیها و collapse_addresses
- مستنداتِ رسمیِ Nginx؛ ترتیبِ allow و deny و وراثتِ قواعد
بررسی منابع: ۳۰ مهر ۱۴۰۵. تحلیلها و پیشنهادهای اجرایی، جمعبندی نویسندهاند.

