แแแแแ แฏแแแ, แฐแแแ แแฃแแแ แแแ. แแฆแแก แแแแแ แแแกแแฃแแ แ แแแแแ, แแฃ แ แแแแ แฃแแแ แแแฌแแ แแ แแฅแแแแ แกแแแฃแแแ แ แแแ แขแแแ NTP แแแแแแขแ. แซแแ แแแแแแ, แกแแฃแแแ แ แแฎแแแ แแแแแขแแก แกแขแ แฃแฅแขแฃแ แแก แแ NTP แกแแ แแแ แแก แแแกแฃแฎแแก แแแแฃแจแแแแแแก แแแแแแก. แแแแ แแแแฌแแ แแแ แแแแแแจแ, แ แแแแแ แแแฉแแแแแแ, แ แแ แแกแแแ แ แแแแแแแกแแแแก แฃแแแแแกแ แแแ แฃแแ แแแแ แแ แแ แกแแแแแก. แแชแแแแแแแ แจแแแแจแแแแแ แแแแแก แแกแแแแกแแแแก ntplib แแแแแแ - แแ "แจแแแแแแแแฃแแ" แแแงแแแ แแแแ.
แ แ แแ แแก แแฃแกแขแแ NTP? NTP แแ แแก แแ แแขแแแแแ แแฃแกแขแ แแ แแแก แกแแ แแแ แแแแแ แฃแ แแแแ แแแแแกแแแแก. แแก แแ แแขแแแแแ แแแแแแงแแแแแ แแแแ แแแแแแแแ แแแ แแแแฅแแแแจแ. แแแแแแแแแ, w32tm แกแแ แแแกแ Windows-แจแ.
แกแฃแ NTP แแ แแขแแแแแแก 5 แแแ แกแแแ. แแแ แแแแ, แแแ แกแแ 0 (1985, RFC958)), แแแแแแแ แแแซแแแแแแฃแแแ แแแแแแแ. แแฎแแ แแแแแแงแแแแแ แฃแคแ แ แแฎแแแ, 1-แแ (1988, RFC1059), แแ-2 (1989, RFC1119), แแ-3 (1992, RFC1305) แแ แแ-4 (1996, RFC2030). แแแ แกแแแแ 1-4 แแแแกแแแแแแ แแ แแแแแแแแแ, แแกแแแ แแแแกแฎแแแแแแแแแ แแฎแแแแ แกแแ แแแ แแก แแฃแจแแแแแก แแแแแ แแแแแแจแ.
แแแแแขแแก แคแแ แแแขแ
แแแฎแขแแแแก แแแฉแแแแแแแแ (แแแ แแฅแขแแ แแแแก แแแฉแแแแแแแแ) - แ แแชแฎแแ, แ แแแแแแช แแแฃแแแแแแก แแแคแ แแฎแแแแแแก แแแแ แแแแแชแแแก แจแแกแแฎแแ แฌแแแแก แจแแกแแฎแแ. แแแแจแแแแแแแ:
- 0 - แแ แแแแแ แ แจแแกแฌแแ แแแ
- 1 - แแฆแแก แแแแ แฌแฃแแ แจแแแชแแแก 61 แฌแแแก
- 2 - แแฆแแก แแแแ แฌแฃแแ แจแแแชแแแก 59 แฌแแแก
- 3 - แกแแ แแแ แแก แแแฃแแแ แแแแแ (แแ แ แแ แแ แแก แกแแแฅแ แแแแแแแฃแแ)
แแแ แกแแแก แแแแแ แ (แแแ แกแแแก แแแแแ แ) โ NTP แแ แแขแแแแแแก แแแ แกแแแก แแแแแ แ (1-4).
แ แแแแแ (แ แแแแแ) - แแแแแขแแก แแแแแแแแแแก แแฃแจแแแแแก แ แแแแแ. แแแแจแแแแแแแ 0-แแแ 7-แแแ, แงแแแแแแ แแแแ แชแแแแแฃแแ:
- 3 - แแแแแแขแ
- 4 - แกแแ แแแ แ
- 5 - แแแฃแฌแงแแแแแแแก แ แแแแแ
แกแขแ แแขแฃแแ (แคแแแแก แแแแ) โ แจแฃแแแแแฃแ แ แคแแแแแแก แ แแแแแแแแ แกแแ แแแ แกแ แแ แกแแชแแแแแ แ แกแแแแก แจแแ แแก (1 โ แกแแ แแแ แ แแฆแแแก แแแแแชแแแแแก แฃแจแฃแแแแ แกแแชแแแแแ แ แกแแแแแกแแแ, 2 โ แกแแ แแแ แ แแฆแแแก แแแแแชแแแแแก 1-แแ แคแแแแก แแฅแแแ แกแแ แแแ แแแแ แแ แ.แจ.).
Pool แแ แแก แฎแแแแแฌแแ แแแ แแแแแ แ แแชแฎแแ, แ แแแแแแช แฌแแ แแแแแแแแก แแแฅแกแแแแแฃแ แแแขแแ แแแแก แแแแแแแ แจแแขแงแแแแแแแแแก แจแแ แแก. NTP แแแแแแขแ แแฅ แแแแกแแแฆแแ แแแก แแแขแแ แแแแก, แ แแแแแแแช แแก แแแแแแแ แกแแ แแแ แแก แแแแแแแแฎแแแก, แฎแแแ NTP แกแแ แแแ แ แแแแกแแแฆแแ แแแก แแแขแแ แแแแก, แ แแแแแก แแ แแกแแช แแก แแแแแแแ แแแแแแแแฎแแแก. แแแแจแแแแแแแ แฃแแ แแก แฌแแแแแแก แแแแแ แฃแ แแแแแ แแแแก.
แกแแแฃแกแขแ (แกแแแฃแกแขแ) แแ แแก แฎแแแแแฌแแ แแแ แแแแแ แ แแชแฎแแ, แ แแแแแแช แฌแแ แแแแแแแแก แกแแกแขแแแแก แกแแแแแก แกแแแฃแกแขแแก. แแแแจแแแแแแแ แฃแแ แแก แฌแแแแแแก แแแแแ แฃแ แแแแแ แแแแก.
แคแแกแแแก แจแแคแแ แฎแแแ (แกแแ แแแ แแก แแแงแแแแแแ) โ แแ แ, แ แแแแแแช แกแญแแ แแแแ แกแแแแแก แฌแแแแแฎแแแแก NTP แกแแ แแแ แแแแ แแแกแแกแแแแแแ, แฌแแแแแแก แคแแฅแกแแ แแแฃแแ แฌแแ แขแแแแก แกแแฎแแ.
แคแแกแแแแแก แแแกแแแ แกแแ (แกแแ แแแ แแก แแแแ แชแแแแแ) - NTP แกแแ แแแ แแก แกแแแแแก แฌแแแแแฎแแแก แแแแ แชแแแแแ, แ แแแแ แช แฌแแแแแแก แ แแแแแแแแ แคแแฅแกแแ แแแฃแแ แฌแแ แขแแแแ.
Ref id (แฌแงแแ แแก แแแแแขแแคแแแแขแแ แ) โ แกแแแแแก id. แแฃ แกแแ แแแ แก แแฅแแก แคแแแ 1, แแแจแแ ref id แแ แแก แแขแแแฃแ แ แกแแแแแก แกแแฎแแแ (4 ASCII แกแแแแแแ). แแฃ แกแแ แแแ แ แแงแแแแแก แกแฎแแ แกแแ แแแ แก, แแแจแแ ref id แจแแแชแแแก แแ แกแแ แแแ แแก แแแกแแแแ แแก.
แแแแ 4 แแแแ แฌแแ แแแแแแแแก แแ แแก - 32 แแแขแ - แแแแแ แ แแชแฎแแ, 32 แแแขแ - แฌแแแแแ แแแฌแแแ.
Reference โ แฃแแฎแแแกแ แกแแแแแก แฉแแแแแแแแ แกแแ แแแ แแ.
แฌแแ แแแจแแแ โ แแ แ, แ แแแแกแแช แแแแแแแแแ แแแแแขแ (แจแแแกแแแฃแแแ แกแแ แแแ แแก แแแแ - แแแขแ แแแแก แจแแกแแฎแแ แฅแแแแแ).
แแแแฆแแ โ แกแแ แแแ แแก แแแแ แแแแแขแแก แแแฆแแแแก แแ แ.
แแแแแชแแแ โ แกแแ แแแ แแแแ แแแแแแขแแกแแแแก แแแแแขแแก แแแแแแแแแก แแ แ (แจแแแกแแแฃแแแ แแแแแแขแแก แแแแ , แแแแก แจแแกแแฎแแ แแ แชแแแ แฅแแแแแ).
แฉแแแ แแ แแแแแแฎแแแแแ แแแแ แแ แแแแก.
แแแแแ แแแแฌแแ แแ แฉแแแแ แแแแแขแ:
แแแแแขแแก แแแแ
class NTPPacket:
_FORMAT = "!B B b b 11I"
def __init__(self, version_number=2, mode=3, transmit=0):
# Necessary of enter leap second (2 bits)
self.leap_indicator = 0
# Version of protocol (3 bits)
self.version_number = version_number
# Mode of sender (3 bits)
self.mode = mode
# The level of "layering" reading time (1 byte)
self.stratum = 0
# Interval between requests (1 byte)
self.pool = 0
# Precision (log2) (1 byte)
self.precision = 0
# Interval for the clock reach NTP server (4 bytes)
self.root_delay = 0
# Scatter the clock NTP-server (4 bytes)
self.root_dispersion = 0
# Indicator of clocks (4 bytes)
self.ref_id = 0
# Last update time on server (8 bytes)
self.reference = 0
# Time of sending packet from local machine (8 bytes)
self.originate = 0
# Time of receipt on server (8 bytes)
self.receive = 0
# Time of sending answer from server (8 bytes)
self.transmit = transmit
แกแแ แแแ แแ แแแแแขแแก แแแกแแแแแแแแ (แแ แแแกแแฆแแแแ) แฃแแแ แจแแแซแแแ แแแกแ แแแแแฅแชแแแ แแแแขแแก แแแกแแแแ.
แแ (แแ แกแแแแ แแกแแแ แ) แแแแ แแชแแแกแแแแก แฉแแแ แแแแฌแแ แ แแ แคแฃแแฅแชแแแก - pack() แแ unpack():
แแแแแขแแก แคแฃแแฅแชแแ
def pack(self):
return struct.pack(NTPPacket._FORMAT,
(self.leap_indicator << 6) +
(self.version_number << 3) + self.mode,
self.stratum,
self.pool,
self.precision,
int(self.root_delay) + get_fraction(self.root_delay, 16),
int(self.root_dispersion) +
get_fraction(self.root_dispersion, 16),
self.ref_id,
int(self.reference),
get_fraction(self.reference, 32),
int(self.originate),
get_fraction(self.originate, 32),
int(self.receive),
get_fraction(self.receive, 32),
int(self.transmit),
get_fraction(self.transmit, 32))
แจแแคแฃแแแแก แคแฃแแฅแชแแ
def unpack(self, data: bytes):
unpacked_data = struct.unpack(NTPPacket._FORMAT, data)
self.leap_indicator = unpacked_data[0] >> 6 # 2 bits
self.version_number = unpacked_data[0] >> 3 & 0b111 # 3 bits
self.mode = unpacked_data[0] & 0b111 # 3 bits
self.stratum = unpacked_data[1] # 1 byte
self.pool = unpacked_data[2] # 1 byte
self.precision = unpacked_data[3] # 1 byte
# 2 bytes | 2 bytes
self.root_delay = (unpacked_data[4] >> 16) +
(unpacked_data[4] & 0xFFFF) / 2 ** 16
# 2 bytes | 2 bytes
self.root_dispersion = (unpacked_data[5] >> 16) +
(unpacked_data[5] & 0xFFFF) / 2 ** 16
# 4 bytes
self.ref_id = str((unpacked_data[6] >> 24) & 0xFF) + " " +
str((unpacked_data[6] >> 16) & 0xFF) + " " +
str((unpacked_data[6] >> 8) & 0xFF) + " " +
str(unpacked_data[6] & 0xFF)
self.reference = unpacked_data[7] + unpacked_data[8] / 2 ** 32 # 8 bytes
self.originate = unpacked_data[9] + unpacked_data[10] / 2 ** 32 # 8 bytes
self.receive = unpacked_data[11] + unpacked_data[12] / 2 ** 32 # 8 bytes
self.transmit = unpacked_data[13] + unpacked_data[14] / 2 ** 32 # 8 bytes
return self
แแแ แแแชแ แแแแแแแแแแแกแแแแก, แ แแแแ แช แแแแแแแชแแ - แแแแ, แ แแแแแแช แแแแแขแก แแแแแ แกแขแ แแแแแ แแฅแชแแแก
def to_display(self):
return "Leap indicator: {0.leap_indicator}n"
"Version number: {0.version_number}n"
"Mode: {0.mode}n"
"Stratum: {0.stratum}n"
"Pool: {0.pool}n"
"Precision: {0.precision}n"
"Root delay: {0.root_delay}n"
"Root dispersion: {0.root_dispersion}n"
"Ref id: {0.ref_id}n"
"Reference: {0.reference}n"
"Originate: {0.originate}n"
"Receive: {0.receive}n"
"Transmit: {0.transmit}"
.format(self)
แกแแ แแแ แแ แแแแแขแแก แแแแแแแแ
แกแแ แแแ แแ แฃแแแ แแแแแแแแแแก แแแแแขแ แจแแแกแแแฃแแ แแแแแแแ แแแแแแฃแ แ, แ แแแแแ ะธ แแแแแชแแแ. In แแแแแชแแแ แแฅแแแ แฃแแแ แแแฃแแแแแ แแแแแแแแ แ แแ แ แแแแแแฃแ แแแแฅแแแแแ (แฌแแแแแแก แ แแแแแแแแ 1 แฌแแแก 1900 แแแแแ แแแแ), แแแ แกแแ - แแแแแกแแแแ แ 1-4, แ แแแแแ - 3 (แแแแแแขแแก แ แแแแแ).
แกแแ แแแ แ, แ แแแแแแแช แแแแฆแ แแแแฎแแแแ, แแแกแแแก แงแแแแ แแแแก NTP แแแแแขแจแ, แแแแแ แแแ แแแแจแ แฌแแ แแแจแแแ แฆแแ แแแฃแแแแ แกแแฌแงแแกแ แแแแแชแแแ, แ แแแแแแช แแแแแแ แแแแฎแแแแแจแ. แฉแแแแแแก แกแแแแฃแแแแ, แ แแขแแ แแ แจแแฃแซแแแ แแแแแแขแก แแแฃแงแแแแแแแแ แจแแแแกแแก แแแแแกแ แแ แแแก แฆแแ แแแฃแแแแ แกแคแแ แแจแ แฌแแ แแแจแแแ. แจแแแแแแ, แ แแแแกแแช แแแแแขแ แแ แฃแแแแแ, แแแแแแขแก แแฅแแก 4 แแ แแแก แแแแจแแแแแแแ - แแแแฎแแแแแก แแแแแแแแแก แแ แ (แฌแแ แแแจแแแ), แ แแแแกแแช แกแแ แแแ แแ แแแแฆแ แแแแฎแแแแ (แแแแฆแแ), แ แแแแกแแช แกแแ แแแ แแ แแแแแแแแแแแ แแแกแฃแฎแ (แแแแแชแแแ) แแ แแแแแแขแแ แแแกแฃแฎแแก แแแฆแแแแก แแ แ โ แฉแแแแกแแแ (แแแแแขแจแ แแ แแ แแก). แแ แแแแจแแแแแแแแแแก แแแแแงแแแแแแ แฉแแแ แจแแแแแซแแแ แแแแแงแแแแ แกแฌแแ แ แแ แ.
แแแแแขแแก แแแแแแแแแก แแ แแแฆแแแแก แแแแ
# Time difference between 1970 and 1900, seconds
FORMAT_DIFF = (datetime.date(1970, 1, 1) - datetime.date(1900, 1, 1)).days * 24 * 3600
# Waiting time for recv (seconds)
WAITING_TIME = 5
server = "pool.ntp.org"
port = 123
packet = NTPPacket(version_number=2, mode=3, transmit=time.time() + FORMAT_DIFF)
answer = NTPPacket()
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.settimeout(WAITING_TIME)
s.sendto(packet.pack(), (server, port))
data = s.recv(48)
arrive_time = time.time() + FORMAT_DIFF
answer.unpack(data)
แกแแ แแแ แแแแ แแแแแชแแแแแแก แแแแฃแจแแแแแ
แกแแ แแแ แแแแ แแแแแชแแแแแแก แแแแฃแจแแแแแ แฐแแแแก แแแแแแกแแแ แฏแแแขแแแแแแก แฅแแแแแแแแก แ แแแแแแ แ. แกแแฃแแแแแแก แซแแแแ แแ แแแแแแแกแแแ (1978): โแแ แ แแแชแก แแ แฐแฅแแแแ แแแฏแแก แกแแแแ, แแแแ แแ แกแแฎแแจแ แแงแ แแฃแกแขแ แแแแแแก แกแแแแ, แ แแแแแกแแช แแแแฏแแ แแแแฌแงแแแแ. แฅแแ แแกแแแ. แแ แ แแฆแแกแแช แแแแแแฌแงแแ แกแแแแแก แแกแแ แฉแแฎแแแแ, แแแแแแแ แแแ แฌแแแแแ, แกแแฆแแแ แแแกแแแ แแแแขแแ แ แแ แกแแฎแแจแ แแแแ แฃแแแแฃแแแ แแแแฎแแ แฎแ แกแแแแแก แกแฌแแ แแ แแแงแแแแแ. แ แแแแ แแแแฎแแ แฎแ แแแ แแก, แแฃ แแแแแแ แแแแก แแ แ แฌแแแแกแฌแแ แแ แแงแ แชแแแแแแ? แแแกแฃแฎแ แแกแแแแ: โแกแแฎแแแแแ แแแกแแแแกแแก แแแแแแแแ แแฎแแแแก แกแแแแก แแ แแฎแกแแแก แ แ แแแแแชแแแจแแ แฎแแแแแ. แแแแแแแ แแแ แแแกแแแแกแแก แแ แกแขแฃแแ แแแแก แแแขแแแแแแก แจแแแแแ แแก แแฆแแแจแแแแก แแแกแแแแกแ แแ แแแแแแแแ แแแแก แแ แแก. แแก แกแแจแฃแแแแแแก แแซแแแแก แแแก แแแแ แแแแแก แ แแแแแ แฎแแแก แกแขแฃแแ แแแแ. แกแแฎแแจแ แแแแ แฃแแแแฃแแ แแ แกแแแแแก แแแแแแแแแ แแแแกแแก แแแแแแแแ แแแแกแแแฆแแ แแแก แแแกแ แแ แงแแคแแแก แฎแแแแ แซแแแแแแแก. แแ แแ แแแแแ แแแแแแแแแแ แแก แแ แ, แ แแแแแกแแช แแก แกแขแฃแแ แแแแ, แแแแแแแแ แแแแแก แแฅ แแ แฃแแแ แแแแแแฃแ แแแแก แแ แแก แแแขแแ แแแฃแ แแ แแก. แแแแแ แแแขแแ แแแฃแแ แแ แแแก แแแฎแแแแ แ แกแขแฃแแ แแแแก แฌแแกแแแแก แแ แแแ แแแแแขแแแแ, แแก แแฆแแแก แจแแกแแซแแแแแแแแก แแแแ แแแแแก แกแแฎแแจแ แแแกแแแแก แแ แ แแ แจแแกแแแแแแกแแ แแแแ แแแฃแแแ แแก แกแแแแแก แแกแ แแแโ.
แแแแแแ แแ แ, แ แแแแกแแช แกแแ แแแ แ แแฃแจแแแแก แแแแฎแแแแแแ:
- แแแแแแ แแแแแขแแก แแแแแแฃแ แแแแก แแ แ แแแแแแขแแแแ แกแแ แแแ แแแแ: ((แฉแแแแกแแแ โ แฌแแ แแแจแแแ) โ (แแแแแชแแแ โ แแแฆแแแ)) / 2
- แแแแแแแ แแแแกแฎแแแแแแ แแแแแแขแกแ แแ แกแแ แแแ แแก แแ แแก แจแแ แแก:
Receive - Originate - ((Arrive - Originate) - (Transmit - Receive)) / 2 =
2 * แแแฆแแแ โ 2 * แฌแแ แแแจแแแ โ แฉแแแแกแแแ + แฌแแ แแแจแแแ + แแแแแชแแแ โ แแแฆแแแ =
แแแฆแแแ โ แฌแแ แแแจแแแ โ แฉแแแแกแแแ + แแแแแชแแแ
แแแฆแแแฃแ แแแแจแแแแแแแแก แแแแแขแแแ แแแแแแแแ แแ แแ แแก แแ แแขแแแแแแ แชแฎแแแ แแแแ.
แจแแแแแแก แแแแแแแแแแ
time_different = answer.get_time_different(arrive_time)
result = "Time difference: {}nServer time: {}n{}".format(
time_different,
datetime.datetime.fromtimestamp(time.time() + time_different).strftime("%c"),
answer.to_display())
print(result)
แกแแกแแ แแแแแ
แฌแงแแ แ: www.habr.com