ืฉืจื™ื™ื‘ืŸ ืึท ืคึผืฉื•ื˜ NTP ืงืœื™ืขื ื˜

ื”ืขืœื ื”ืึทื‘ืจืึทื•ื–ืขืจื–. ื”ื™ื™ึทื ื˜ ืื™ืš ื•ื•ื™ืœืŸ ืฆื• ืจืขื“ืŸ ื•ื•ืขื’ืŸ ื•ื•ื™ ืฆื• ืฉืจื™ื™ึทื‘ืŸ ื“ื™ื™ืŸ ืื™ื™ื’ืขื ืข ืคึผืฉื•ื˜ NTP ืงืœื™ืขื ื˜. ื‘ื™ื™ืกื™ืงืœื™, ื“ื™ ืฉืžื•ืขืก ื•ื•ืขื˜ ืงืขืจ ืฆื• ื“ื™ ืกื˜ืจื•ืงื˜ื•ืจ ืคื•ืŸ ื“ื™ ืคึผืึทืงืึทื˜ ืื•ืŸ ื•ื•ื™ ื“ื™ ืขื ื˜ืคืขืจ ืคื•ืŸ ื“ื™ NTP ืกืขืจื•ื•ืขืจ ืื™ื– ืคึผืจืึทืกืขืกื˜. ื“ืขืจ ืงืึธื“ ื•ื•ืขื˜ ื–ื™ื™ืŸ ื’ืขืฉืจื™ื‘ืŸ ืื™ืŸ ืคึผื™ื˜ื”ืึธืŸ, ื•ื•ื™ื™ึทืœ, ืื™ืŸ ืžื™ื™ืŸ ืžื™ื™ื ื•ื ื’, ืขืก ืื™ื– ืคืฉื•ื˜ ืงื™ื™ืŸ ื‘ืขืกืขืจ ืฉืคึผืจืึทืš ืคึฟืึทืจ ืึทื–ืึท ื–ืื›ืŸ. ืงืึทื ืึทืกืขืจื– ื•ื•ืขื˜ ื‘ืึทืฆืึธืœืŸ ื•ืคืžืขืจืงื–ืึทืžืงื™ื™ื˜ ืฆื• ื“ื™ ืขื ืœืขื›ืงื™ื™ื˜ ืคื•ืŸ ื“ื™ ืงืึธื“ ืžื™ื˜ ื“ื™ ื ื˜ืคึผืœื™ื‘ ืงืึธื“ - ืื™ืš ืื™ื– ื’ืขื•ื•ืขืŸ "ื™ื ืกืคึผื™ื™ืขืจื“" ื“ื•ืจืš ืขืก.

ืึทื–ื•ื™ ื•ื•ืึธืก ืื™ื– NTP ืกื™ื™ึท ื•ื•ื™ ืกื™ื™ึท? NTP ืื™ื– ืึท ืคึผืจืึธื˜ืึธืงืึธืœ ืคึฟืึทืจ ืงืึทืžื™ื•ื ืึทืงื™ื™ื˜ื™ื ื’ ืžื™ื˜ ืฆื™ื™ื˜ ืกืขืจื•ื•ืขืจืก. ื“ืขื ืคึผืจืึธื˜ืึธืงืึธืœ ืื™ื– ื’ืขื ื™ืฆื˜ ืื™ืŸ ืคื™ืœืข ืžืึธื“ืขืจืŸ ืžืืฉื™ื ืขืŸ. ืคึฟืึทืจ ื‘ื™ื™ึทืฉืคึผื™ืœ, ื“ื™ w32tm ื“ื™ื ืกื˜ ืื•ื™ืฃ Windows.

ืขืก ื–ืขื ืขืŸ 5 ื•ื•ืขืจืกื™ืขืก ืคื•ืŸ ื“ื™ NTP ืคึผืจืึธื˜ืึธืงืึธืœ ืื™ืŸ ื’ืึทื ืฅ. ื“ืขืจ ืขืจืฉื˜ืขืจ ื•ื•ืขืจืกื™ืข 0 (1985, RFC958) ืื™ื– ื“ืขืจื•ื•ื™ื™ึทืœ ื’ืขืจืขื›ื ื˜ ื•ื•ื™ ืคืึทืจืขืœื˜ืขืจื˜. ื“ืขืจื•ื•ื™ื™ึทืœ, ื ื™ื™ึทืขืจ ืึธื ืขืก ื–ืขื ืขืŸ ื’ืขื ื™ืฆื˜, 1 (1988, RFC1059), 2 (1989, RFC1119), 3 (1992, RFC1305) ืื•ืŸ 4 (1996, RFC2030). ื•ื•ืขืจืกื™ืขืก 1-4 ื–ืขื ืขืŸ ืงืึทืžืคึผืึทื˜ืึทื‘ืึทืœ ืžื™ื˜ ื™ืขื“ืขืจ ืื ื“ืขืจืข, ื–ื™ื™ ื–ืขื ืขืŸ ืึทื ื“ืขืจืฉ ื‘ืœื•ื™ื– ืื™ืŸ ื“ื™ ืึทืœื’ืขืจื™ื“ืึทืžื– ืคื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจืก.

ืคึผืึทืงืึทื˜ ืคึฟืึธืจืžืึทื˜

ืฉืจื™ื™ื‘ืŸ ืึท ืคึผืฉื•ื˜ NTP ืงืœื™ืขื ื˜

ืฉืคึผืจื™ื ื’ืขืŸ ื’ืจืื“ืŸ (ืงืขืจืขืงืฉืึทืŸ ื’ืจืื“ืŸ) ืื™ื– ืึท ื ื•ืžืขืจ ื•ื•ืึธืก ื™ื ื“ื™ืงื™ื™ืฅ ื“ื™ ืฉืคึผืจื™ื ื’ืขืŸ ืจื’ืข ื•ื•ืืจืขื ื•ื ื’. ื˜ื™ื™ึทื˜ืฉ:

  • 0 - ืงื™ื™ืŸ ืงืขืจืขืงืฉืึทืŸ
  • 1 - ื“ื™ ืœืขืฆื˜ืข ืžื™ื ื•ื˜ ืคื•ืŸ ื“ืขื ื˜ืึธื’ ื›ึผื•ืœืœ 61 ืกืขืงื•ื ื“ืขืก
  • 2 - ื“ื™ ืœืขืฆื˜ืข ืžื™ื ื•ื˜ ืคื•ืŸ ื“ืขื ื˜ืึธื’ ื›ึผื•ืœืœ 59 ืกืขืงื•ื ื“ืขืก
  • 3 - ืกืขืจื•ื•ืขืจ ื“ื•ืจื›ืคืึทืœ (ืฆื™ื™ื˜ ืื•ื™ืก ืคื•ืŸ ืกื™ื ืง)

ื•ื•ืขืจืกื™ืข ื ื•ืžืขืจ (ื•ื•ืขืจืกื™ืข ื ื•ืžืขืจ) - NTP ืคึผืจืึธื˜ืึธืงืึธืœ ื•ื•ืขืจืกื™ืข ื ื•ืžืขืจ (1-4).

ืžืึธื“ืข (ืžืึธื“ืข) - ืึธืคึผืขืจืึทืฆื™ืข ืžืึธื“ืข ืคื•ืŸ โ€‹โ€‹ื“ื™ ืคึผืึทืงืึทื˜ ืกืขื ื“ืขืจ. ื•ื•ืขืจื˜ ืคื•ืŸ 0 ืฆื• 7, ืžืขืจืกื˜ ืคึผืจืึธืกื˜:

  • 3 - ืงืœื™ืขื ื˜
  • 4 - ืกืขืจื•ื•ืขืจ
  • 5 - ื‘ืจืึธื“ืงืึทืกื˜ ืžืึธื“ืข

ืฉื™ื›ื˜ืข (ืœื™ื™ืขืจื™ื ื’ ืžื“ืจื’ื”) - ื“ื™ ื ื•ืžืขืจ ืคื•ืŸ ื™ื ื˜ืขืจืžื™ื“ื™ื™ื˜ ืœื™ื™ึทืขืจืก ืฆื•ื•ื™ืฉืŸ ื“ื™ ืกืขืจื•ื•ืขืจ ืื•ืŸ ื“ื™ ืจืขืคึฟืขืจืขื ืฅ ื–ื™ื™ื’ืขืจ (1 - ื“ืขืจ ืกืขืจื•ื•ืขืจ ื ืขืžื˜ ื“ืึทื˜ืŸ ื’ืœื™ื™ึทืš ืคื•ืŸ ื“ื™ ืจืขืคึฟืขืจืขื ืฅ ื–ื™ื™ื’ืขืจ, 2 - ื“ืขืจ ืกืขืจื•ื•ืขืจ ื ืขืžื˜ ื“ืึทื˜ืŸ ืคึฟื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจ ืžื™ื˜ ืžื“ืจื’ื” 1, ืืื–"ื• ื•).
ื‘ืขืงืŸ ืื™ื– ืึท ื’ืขื—ืชืžืขื˜ ื’ืึทื ืฅ ื ื•ืžืขืจ ืจืขืคึผืจื™ื–ืขื ื˜ื™ื ื’ ื“ื™ ืžืึทืงืกื™ืžื•ื ืžืขื”ืึทืœืขืš ืฆื•ื•ื™ืฉืŸ ืงืึธื ืกืขืงื•ื˜ื™ื•ื•ืข ืึทืจื˜ื™ืงืœืขืŸ. ื“ืขืจ NTP ืงืœื™ืขื ื˜ ืกืคึผืขืฆื™ืคื™ืฆื™ืจื˜ ื“ืึธ ื“ื™ ืžืขื”ืึทืœืขืš ืื™ืŸ ื•ื•ืึธืก ืขืจ ื™ืงืกืคึผืขืงืฅ ืฆื• ื‘ืึทืงื•ืžืขืŸ ื“ื™ ืกืขืจื•ื•ืขืจ, ืื•ืŸ ื“ืขืจ NTP ืกืขืจื•ื•ืขืจ ืกืคึผืขืฆื™ืคื™ืฆื™ืจื˜ ื“ื™ ืžืขื”ืึทืœืขืš ืื™ืŸ ื•ื•ืึธืก ืขืก ื™ืงืกืคึผืขืงืฅ ืฆื• ื–ื™ื™ืŸ ืคึผืึธื•ืœื“. ื“ื™ ื•ื•ืขืจื˜ ืื™ื– ื’ืœื™ื™ึทืš ืฆื• ื“ื™ ื‘ื™ื™ื ืขืจื™ ืœืึธื’ืึทืจื™ื˜ื”ื ืคื•ืŸ ืกืขืงื•ื ื“ืขืก.
ืคึผื™ื ื˜ืœืขื›ืงื™ื™ึทื˜ (ืคึผื™ื ื˜ืœืขื›ืงื™ื™ึทื˜) ืื™ื– ืึท ื’ืขื—ืชืžืขื˜ ื’ืึทื ืฅ ื ื•ืžืขืจ ืจืขืคึผืจื™ื–ืขื ื˜ื™ื ื’ ื“ื™ ืึทืงื™ืขืจืึทืกื™ ืคื•ืŸ ื“ื™ ืกื™ืกื˜ืขื ื–ื™ื™ื’ืขืจ. ื“ื™ ื•ื•ืขืจื˜ ืื™ื– ื’ืœื™ื™ึทืš ืฆื• ื“ื™ ื‘ื™ื™ื ืขืจื™ ืœืึธื’ืึทืจื™ื˜ื”ื ืคื•ืŸ ืกืขืงื•ื ื“ืขืก.
ื•ื•ืึธืจืฆืœ ืคืึทืจื”ืึทืœื˜ืŸ (ืกืขืจื•ื•ืขืจ ืœื™ื™ื˜ืึทื ืกื™) ืื™ื– ื“ื™ ืฆื™ื™ื˜ ืขืก ื ืขืžื˜ ืคึฟืึทืจ ื“ื™ ื–ื™ื™ื’ืขืจ ืฆื• ื“ืขืจื’ืจื™ื™ื›ืŸ ื“ื™ NTP ืกืขืจื•ื•ืขืจ, ื•ื•ื™ ืึท ืคืึทืจืคืขืกื˜ื™ืงื˜ ื ื•ืžืขืจ ืคื•ืŸ ืกืขืงื•ื ื“ืขืก.
ื•ื•ืึธืจืฆืœ ื“ื™ืกืคึผืขืจืฉืึทืŸ (ืกืขืจื•ื•ืขืจ ืฆืขื•ื•ืึธืจืคืŸ) - ื“ื™ ืฆืขื•ื•ืึธืจืคืŸ ืคื•ืŸ ื“ื™ NTP ืกืขืจื•ื•ืขืจ ื–ื™ื™ื’ืขืจ ื•ื•ื™ ืึท ืคืึทืจืคืขืกื˜ื™ืงื˜-ืคื•ื ื˜ ื ื•ืžืขืจ ืคื•ืŸ ืกืขืงื•ื ื“ืขืก.
Ref ID (ืžืงื•ืจ ืฉื™ื™ึทืŸ) - ื•ื•ืึทืš ืฉื™ื™ึทืŸ. ืื•ื™ื‘ ื“ืขืจ ืกืขืจื•ื•ืขืจ ื”ืื˜ ืกื˜ืจืึทื˜ื•ื 1, ืจืขืฃ ืฉื™ื™ึทืŸ ืื™ื– ื“ืขืจ ื ืึธืžืขืŸ ืคื•ืŸ ื“ื™ ืึทื˜ืึธืžื™ืฉืข ื–ื™ื™ื’ืขืจ (4 ASCII ืื•ืชื™ื•ืช). ืื•ื™ื‘ ื“ืขืจ ืกืขืจื•ื•ืขืจ ื ื™ืฆื˜ ืืŸ ืื ื“ืขืจ ืกืขืจื•ื•ืขืจ, ื“ืขืจ ืจืขืฃ ืฉื™ื™ึทืŸ ื›ึผื•ืœืœ ื“ื™ ืึทื“ืจืขืก ืคื•ืŸ ื“ืขื ืกืขืจื•ื•ืขืจ.
ื“ื™ ืœืขืฆื˜ืข 4 ืคืขืœื“ืขืจ ืจืขืคึผืจืึทื–ืขื ืฅ ื“ื™ ืฆื™ื™ื˜ - 32 ื‘ื™ืฅ - ื“ื™ ื™ื ื˜ืึทื“ื–ืฉืขืจ ื˜ื™ื™ืœ, 32 ื‘ื™ืฅ - ื“ื™ ืคืจืึทืงืฉืึทื ืึทืœ ื˜ื™ื™ืœ.
ื“ืขืจืžืึธื ืขืŸ - ื“ื™ ืœืขืฆื˜ืข ื–ื™ื™ื’ืขืจ ืื•ื™ืฃ ื“ื™ ืกืขืจื•ื•ืขืจ.
ืึธืจื™ื’ื™ื ืึทื˜ืข - ืฆื™ื™ื˜ ื•ื•ืขืŸ ื“ื™ ืคึผืึทืงืึทื˜ ืื™ื– ื’ืขืฉื™ืงื˜ (ืึธื ื’ืขืคื™ืœื˜ ื“ื•ืจืš ื“ื™ ืกืขืจื•ื•ืขืจ - ืžืขืจ ื•ื•ืขื’ืŸ ื“ืขื ืื•ื ื˜ืŸ).
ื‘ืึทืงื•ืžืขืŸ - ืฆื™ื™ื˜ ื•ื•ืขืŸ ื“ื™ ืคึผืึทืงืึทื˜ ืื™ื– ื‘ืืงื•ืžืขืŸ ื“ื•ืจืš ื“ื™ ืกืขืจื•ื•ืขืจ.
ื™ื‘ืขืจืฉื™ืงืŸ - ืฆื™ื™ื˜ ื•ื•ืขืŸ ื“ื™ ืคึผืึทืงืึทื˜ ืื™ื– ื’ืขืฉื™ืงื˜ ืคื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจ ืฆื• ื“ืขื ืงืœื™ืขื ื˜ (ืึธื ื’ืขืคื™ืœื˜ ื“ื•ืจืš ื“ืขื ืงืœื™ืขื ื˜, ืžืขืจ ื•ื•ืขื’ืŸ ื“ืขื ืื•ื ื˜ืŸ).

ื“ื™ ืœืขืฆื˜ืข ืฆื•ื•ื™ื™ ืคืขืœื“ืขืจ ื•ื•ืขื˜ ื ื™ื˜ ื–ื™ื™ืŸ ื‘ืึทื˜ืจืึทื›ื˜.

ืœืืžื™ืจ ืฉืจื™ื™ื‘ืŸ ืื•ื ื–ืขืจ ืคืขืงืœ:

ืคึผืขืงืœ ืงืึธื“

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

ืฆื• ืฉื™ืงืŸ (ืื•ืŸ ื‘ืึทืงื•ืžืขืŸ) ืึท ืคึผืึทืงืึทื˜ ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ, ืžื™ืจ ืžื•ื–ืŸ ืงืขื ืขืŸ ืฆื• ื•ื•ืขื ื“ืŸ ืขืก ืื™ืŸ ืึท ืžืขื ื’ืข ืคื•ืŸ โ€‹โ€‹ื‘ื™ื˜ืขืก.
ืคึฟืึทืจ ื“ืขื (ืื•ืŸ ืคืึทืจืงืขืจื˜) ืึธืคึผืขืจืึทืฆื™ืข, ืžื™ืจ ื•ื•ืขืœืŸ ืฉืจื™ื™ึทื‘ืŸ ืฆื•ื•ื™ื™ ืคืึทื ื’ืงืฉืึทื ื– - ืคึผืึทืง () ืื•ืŸ ืึทื ืคึผืึทืง ():

ืคึผืึทืง ืคึฟื•ื ืงืฆื™ืข

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)

ืฉื™ืงื˜ ืึท ืคึผืขืงืœ ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ

ืฉื™ืงืŸ ืึท ืคึผืึทืงืึทื˜ ืžื™ื˜ ืึธื ื’ืขืคื™ืœื˜ ืคืขืœื“ืขืจ ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ ื•ื•ืขืจืกื™ืข, ืžืึธื“ืข ะธ ื™ื‘ืขืจืฉื™ืงืŸ. ื“ื™ ื™ื‘ืขืจืฉื™ืงืŸ ืื™ืจ ืžื•ื–ืŸ ืกืคึผืขืฆื™ืคื™ืฆื™ืจืŸ ื“ื™ ืงืจืึทื ื˜ ืฆื™ื™ื˜ ืื•ื™ืฃ ื“ื™ ื”ื™ื’ืข ืžืึทืฉื™ืŸ (ื ื•ืžืขืจ ืคื•ืŸ ืกืขืงื•ื ื“ืขืก ื–ื™ื ื˜ ื™ืื ื•ืืจ 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)

ื“ืึทื˜ืŸ ืคึผืจืึทืกืขืกื™ื ื’ ืคื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจ

ื“ื™ ืคึผืจืึทืกืขืกื™ื ื’ ืคื•ืŸ ื“ืึทื˜ืŸ ืคื•ืŸ ื“ื™ ืกืขืจื•ื•ืขืจ ืื™ื– ืขื ืœืขืš ืฆื• ื“ื™ ืึทืงืฉืึทื ื– ืคื•ืŸ ื“ื™ ืขื ื’ืœื™ืฉ ื“ื–ืฉืขื ื˜ืœืžืขืŸ ืคื•ืŸ ื“ืขืจ ืึทืœื˜ ืคึผืจืึธื‘ืœืขื ืคื•ืŸ Raymond M. Smallian (1978): "ืื™ื™ืŸ ืžืขื ื˜ืฉ ื”ืื˜ ื ื™ืฉื˜ ื”ืึธื‘ืŸ ืึท ื”ืึทื ื˜ื’ืขืœืขื ืง, ืึธื‘ืขืจ ืขืก ืื™ื– ื’ืขื•ื•ืขืŸ ืึท ืคึผื™ื ื˜ืœืขืš ื•ื•ืึทื ื˜ ื–ื™ื™ื’ืขืจ ืื™ืŸ ืฉื˜ื•ื‘, ื•ื•ืึธืก ืขืจ ืžืืœ ืคืืจื’ืขืกืŸ ืฆื• ื•ื•ื™ื ื˜. ืื™ื™ืŸ ื˜ืื’, ืคืืจื’ืขืื ื“ื™ืง ื•ื•ื™ื“ืขืจ ืื ืฆื•ื”ื•ื™ื‘ืŸ ื“ืขื ื–ื™ื™ื’ืขืจ, ืื™ื– ืขืจ ื’ืขื’ืื ื’ืขืŸ ื‘ืื–ื•ื›ืŸ ื–ื™ื™ืŸ ืคืจื™ื™ื ื“, ืคืืจื‘ืจืื›ื˜ ืžื™ื˜ ืื™ื ื“ืขื ืึธื•ื•ื ื˜, ืื•ืŸ ื•ื•ืขืŸ ืขืจ ืื™ื– ืฆื•ืจื™ืง ืึทื”ื™ื™ื, ืื™ื– ืขืจ ื’ืขืœื•ื ื’ืŸ ืฆื• ืฉื˜ืขืœืŸ ื“ืขื ื–ื™ื™ื’ืขืจ ืจื™ื›ื˜ื™ืง. ื•ื•ื™ ื”ืื˜ ืขืจ ื’ืขืจืื˜ืŸ ืฆื• ื˜ืึธืŸ ื“ืึธืก ืื•ื™ื‘ ื“ื™ ืจื™ื™ื–ืข ืฆื™ื™ื˜ ืื™ื– ื ื™ืฉื˜ ื‘ืืงืื ื˜ ืื™ืŸ ืฉื˜ื™ื™ึทื’ืŸ? ื“ืขืจ ืขื ื˜ืคึฟืขืจ ืื™ื–: โ€žืคึฟืึทืจืœืึธื–ื ื“ื™ืง ืคึฟื•ืŸ ืฉื˜ื•ื‘, ื•ื•ื™ื ื“ื˜ ืึท ืžืขื ื˜ืฉ ืื•ื™ืคึฟืŸ ื–ื™ื™ื’ืขืจ ืื•ืŸ ื’ืขื“ืขื ืงื˜ ื“ื™ ืฉื˜ืขืœืข ืคึฟื•ืŸ ื“ื™ ื”ืขื ื˜. ืงื•ืžืขืŸ ืฆื• ืึท ืคืจื™ื™ึทื ื“ ืื•ืŸ ืœืึธื–ืŸ ื“ื™ ื’ืขืกื˜, ืขืจ ื‘ืืžืขืจืงื˜ ื“ื™ ืฆื™ื™ึทื˜ ืคื•ืŸ ื–ื™ื™ืŸ ืึธื ืงื•ืžืขืŸ ืื•ืŸ ืึทื•ื•ืขืงื’ื™ื™ืŸ. ื“ืึธืก ืึทืœืึทื•ื– ืื™ื ืฆื• ื’ืขืคึฟื™ื ืขืŸ ืื•ื™ืก ื•ื•ื™ ืœืึทื ื’ ืขืจ ืื™ื– ืึทื•ื•ืขืง. ืื•ืžื’ืขืงืขืจื˜ ื”ื™ื™ื ืื•ืŸ ืงื•ืง ื‘ื™ื™ึท ื“ื™ ื–ื™ื™ื’ืขืจ, ืึท ืžืขื ื˜ืฉ ื‘ืึทืฉื˜ื™ืžื˜ ื“ื™ ื’ืขื“ื•ื™ืขืจ ืคื•ืŸ ื–ื™ื™ืŸ ืึทื•ื•ืขืง. ืืจืืคื ืขืžืขืŸ ืคื•ืŸ ื“ืขืจ ืฆื™ื™ื˜ ื“ื™ ืฆื™ื™ื˜ ื•ื•ืืก ืขืจ ื”ืื˜ ืคืืจื‘ืจืื›ื˜ ืฆื• ื‘ืื–ื•ื›ืŸ, ื“ืขืจืžืื ืขืŸ ื“ืขืจ ืžืขื ื˜ืฉ ื“ื™ ืฆื™ื™ื˜ ื•ื•ืืก ืขืจ ืื™ื– ืคืืจื‘ืจืื›ื˜ ืื•ื™ืคืŸ ื•ื•ืขื’ ืื”ื™ืŸ ืื•ืŸ ืฆื•ืจื™ืง. ื“ื•ืจืš ืฆื•ื’ืขื‘ืŸ ื”ืึทืœื‘ ืคื•ืŸ ื“ื™ ืฆื™ื™ื˜ ื•ื•ืึธืก ืื™ื– ืคืืจื‘ืจืื›ื˜ ืื•ื™ืฃ ื“ื™ ื•ื•ืขื’ ืฆื• ื“ื™ ืฆื™ื™ื˜ ืคื•ืŸ ืคืึทืจืœืึธื–ืŸ ื“ื™ ื’ืขืกื˜, ืขืจ ื‘ืึทืงื•ืžืขืŸ ื“ื™ ื’ืขืœืขื’ื ื”ื™ื™ื˜ ืฆื• ื’ืขืคึฟื™ื ืขืŸ ืื•ื™ืก ื“ื™ ืฆื™ื™ื˜ ืคื•ืŸ ืึธื ืงื•ืžืขืŸ ืึทื”ื™ื™ื ืื•ืŸ ืกื˜ืจื•ื™ืขืจืŸ ื“ื™ ื•ื•ื™ื™ื–ื˜ ืคื•ืŸ ื–ื™ื™ืŸ ื–ื™ื™ื’ืขืจ.

ื’ืขืคึฟื™ื ืขืŸ ื“ื™ ืฆื™ื™ื˜ ื•ื•ืึธืก ื“ื™ ืกืขืจื•ื•ืขืจ ืื™ื– ืืจื‘ืขื˜ืŸ ืื•ื™ืฃ ื“ื™ ื‘ืงืฉื”:

  1. ื’ืขืคึฟื™ื ืขืŸ ื“ื™ ืคึผืึทืงืึทื˜ ืจื™ื™ื–ืข ืฆื™ื™ื˜ ืคื•ืŸ ื“ืขื ืงืœื™ืขื ื˜ ืฆื• ื“ื™ ืกืขืจื•ื•ืขืจ: ((ืึธื ืงื•ืžืขืŸ - ืึธืจื™ื’ื™ื ืึทื˜ืข) - (ื˜ืจืึทื ืกืžื™ื˜ - ื‘ืึทืงื•ืžืขืŸ)) / 2
  2. ื’ืขืคึฟื™ื ืขืŸ ื“ื™ ื—ื™ืœื•ืง ืฆื•ื•ื™ืฉืŸ ืงืœื™ืขื ื˜ ืื•ืŸ ืกืขืจื•ื•ืขืจ ืฆื™ื™ื˜:
    ื‘ืึทืงื•ืžืขืŸ - ืึธืจื™ื’ื™ื ืึทื˜ืข - ((ืงื•ืžืขืŸ - ืึธืจื™ื’ื™ื ืึทื˜ืข) - (ื˜ืจืึทื ืกืžื™ื˜ - ื‘ืึทืงื•ืžืขืŸ)) / 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

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’