2022-03-11 11:42:09 +01:00
|
|
|
# --- Day 7: Internet Protocol Version 7 ---
|
|
|
|
|
|
|
|
# While snooping around the local network of EBHQ, you compile a list of IP
|
|
|
|
# addresses (they're IPv7, of course; IPv6 is much too limited). You'd like to
|
|
|
|
# figure out which IPs support TLS (transport-layer snooping).
|
|
|
|
|
|
|
|
# An IP supports TLS if it has an Autonomous Bridge Bypass Annotation, or ABBA.
|
|
|
|
# An ABBA is any four-character sequence which consists of a pair of two
|
|
|
|
# different characters followed by the reverse of that pair, such as xyyx or
|
|
|
|
# abba. However, the IP also must not have an ABBA within any hypernet
|
|
|
|
# sequences, which are contained by square brackets.
|
|
|
|
|
|
|
|
# For example:
|
|
|
|
|
|
|
|
# abba[mnop]qrst supports TLS (abba outside square brackets).
|
|
|
|
# abcd[bddb]xyyx does not support TLS (bddb is within square brackets, even
|
|
|
|
# though xyyx is outside square brackets).
|
|
|
|
# aaaa[qwer]tyui does not support TLS (aaaa is invalid; the interior
|
|
|
|
# characters must be different).
|
|
|
|
# ioxxoj[asdfgh]zxcvbn supports TLS (oxxo is outside square brackets, even
|
|
|
|
# though it's within a larger string).
|
|
|
|
|
|
|
|
# How many IPs in your puzzle input support TLS?
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
with open("files/P7.txt") as f:
|
|
|
|
IPs = [
|
|
|
|
re.split(r"\[([^\]]+)\]", line) for line in f.read().strip().split()
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def abba(s: str) -> bool:
|
|
|
|
for i0, i1, i2, i3 in zip(s, s[1:], s[2:], s[3:]):
|
|
|
|
if i0 == i3 and i1 == i2 and i0 != i1:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def part_1() -> None:
|
2022-03-12 19:23:02 +01:00
|
|
|
tls = 0
|
2022-03-11 11:42:09 +01:00
|
|
|
for ip in IPs:
|
|
|
|
sn, hn = (" ".join(ip[::2]), " ".join(ip[1::2]))
|
|
|
|
if abba(sn) and not (abba(hn)):
|
2022-03-12 19:23:02 +01:00
|
|
|
tls += 1
|
|
|
|
|
|
|
|
print(f"There are {tls} IPs supporting TLS")
|
|
|
|
|
|
|
|
|
|
|
|
# --- Part Two ---
|
|
|
|
|
|
|
|
# You would also like to know which IPs support SSL (super-secret listening).
|
|
|
|
|
|
|
|
# An IP supports SSL if it has an Area-Broadcast Accessor, or ABA, anywhere in
|
|
|
|
# the supernet sequences (outside any square bracketed sections), and a
|
|
|
|
# corresponding Byte Allocation Block, or BAB, anywhere in the hypernet
|
|
|
|
# sequences. An ABA is any three-character sequence which consists of the same
|
|
|
|
# character twice with a different character between them, such as xyx or aba.
|
|
|
|
# A corresponding BAB is the same characters but in reversed positions: yxy and
|
|
|
|
# bab, respectively.
|
|
|
|
|
|
|
|
# For example:
|
|
|
|
|
|
|
|
# aba[bab]xyz supports SSL (aba outside square brackets with corresponding
|
|
|
|
# bab within square brackets).
|
|
|
|
# xyx[xyx]xyx does not support SSL (xyx, but no corresponding yxy).
|
|
|
|
# aaa[kek]eke supports SSL (eke in supernet with corresponding kek in
|
|
|
|
# hypernet; the aaa sequence is not related, because the interior character
|
|
|
|
# must be different).
|
|
|
|
# zazbz[bzb]cdb supports SSL (zaz has no corresponding aza, but zbz has a
|
|
|
|
# corresponding bzb, even though zaz and zbz overlap).
|
|
|
|
|
|
|
|
# How many IPs in your puzzle input support SSL?
|
|
|
|
|
|
|
|
|
|
|
|
def is_aba(s: str) -> list[str]:
|
|
|
|
aba_list = []
|
|
|
|
for i0, i1, i2 in zip(s, s[1:], s[2:]):
|
|
|
|
if i0 == i2 and i0 != i1:
|
|
|
|
aba_list.append("".join([i0, i1, i2]))
|
|
|
|
return aba_list
|
|
|
|
|
|
|
|
|
|
|
|
def part_2() -> None:
|
|
|
|
ssl = 0
|
|
|
|
for ip in IPs:
|
|
|
|
sn, hn = (" ".join(ip[::2]), " ".join(ip[1::2]))
|
|
|
|
aba_list = is_aba(sn)
|
|
|
|
for aba in aba_list:
|
|
|
|
if aba[1] + aba[0] + aba[1] in hn:
|
|
|
|
ssl += 1
|
|
|
|
break
|
|
|
|
|
|
|
|
print(f"There are {ssl} IPs supporting SSL")
|
2022-03-11 11:42:09 +01:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
part_1()
|
2022-03-12 19:23:02 +01:00
|
|
|
part_2()
|