рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрдирдЯреАрдкреА рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд┐рдЦрдирд╛

рд╣реЗрд▓реЛ рд╣рдмреНрд░реВрдЬрд╝рд░реНрд╕. рдЖрдЬ рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рд╕рд░рд▓ рдПрдирдЯреАрдкреА рдХреНрд▓рд╛рдЗрдВрдЯ рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВред рдореВрд▓ рд░реВрдк рд╕реЗ, рдмрд╛рддрдЪреАрдд рдкреИрдХреЗрдЯ рдХреА рд╕рдВрд░рдЪрдирд╛ рдФрд░ рдПрдирдЯреАрдкреА рд╕рд░реНрд╡рд░ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕ рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реЛрдЧреАред рдХреЛрдб рдкрд╛рдпрдерди рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдРрд╕реА рдЪреАрдЬрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕рд╕реЗ рдмреЗрд╣рддрд░ рдХреЛрдИ рднрд╛рд╖рд╛ рдирд╣реАрдВ рд╣реИред рдкрд╛рд░рдЦреА рд▓реЛрдЧ ntplib рдХреЛрдб рдХреЗ рд╕рд╛рде рдХреЛрдб рдХреА рд╕рдорд╛рдирддрд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВрдЧреЗ - рдореИрдВ рдЗрд╕рд╕реЗ "рдкреНрд░реЗрд░рд┐рдд" рд╣реБрдЖ рдерд╛ред

рддреЛ рдлрд┐рд░ рдПрдирдЯреАрдкреА рдХреНрдпрд╛ рд╣реИ? рдПрдирдЯреАрдкреА рдЯрд╛рдЗрдо рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╣реИред рдЗрд╕ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ рдЖрдзреБрдирд┐рдХ рдорд╢реАрдиреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд┐рдВрдбреЛрдЬрд╝ рдкрд░ w32tm рд╕реЗрд╡рд╛ред

NTP рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдХреБрд▓ 5 рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВред рдкрд╣рд▓рд╛, рд╕рдВрд╕реНрдХрд░рдг 0 (1985, рдЖрд░рдПрдлрд╕реА958) рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрдкреНрд░рдЪрд▓рд┐рдд рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдирдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдкрд╣рд▓рд╛ (1, рдЖрд░рдПрдлрд╕реА1988), рджреВрд╕рд░рд╛ (1059, рдЖрд░рдПрдлрд╕реА2), рддреАрд╕рд░рд╛ (1989, рдЖрд░рдПрдлрд╕реА1119) рдФрд░ рдЪреМрдерд╛ (3, рдЖрд░рдПрдлрд╕реА1992)ред рд╕рдВрд╕реНрдХрд░рдг 1305-4 рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реИрдВ, рд╡реЗ рдХреЗрд╡рд▓ рд╕рд░реНрд╡рд░ рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдореЗрдВ рднрд┐рдиреНрди рд╣реИрдВред

рдкреИрдХреЗрдЯ рдкреНрд░рд╛рд░реВрдк

рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрдирдЯреАрдкреА рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд┐рдЦрдирд╛

рдЫрд▓рд╛рдВрдЧ рд╕реВрдЪрдХ (рд╕реБрдзрд╛рд░ рд╕реВрдЪрдХ) рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬреЛ рд▓реАрдк рд╕реЗрдХреЗрдВрдб рдЪреЗрддрд╛рд╡рдиреА рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИред рдЕрд░реНрде:

  • 0 - рдХреЛрдИ рд╕реБрдзрд╛рд░ рдирд╣реАрдВ
  • 1 - рджрд┐рди рдХреЗ рдЕрдВрддрд┐рдо рдорд┐рдирдЯ рдореЗрдВ 61 рд╕реЗрдХрдВрдб рд╣реЛрддреЗ рд╣реИрдВ
  • 2 - рджрд┐рди рдХреЗ рдЕрдВрддрд┐рдо рдорд┐рдирдЯ рдореЗрдВ 59 рд╕реЗрдХрдВрдб рд╣реЛрддреЗ рд╣реИрдВ
  • 3 - рд╕рд░реНрд╡рд░ рд╡рд┐рдлрд▓рддрд╛ (рд╕рдордп рд╕рдордиреНрд╡рдпрди рд╕реЗ рдмрд╛рд╣рд░)

рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛ (рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛) - рдПрдирдЯреАрдкреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рдВрд╕реНрдХрд░рдг рд╕рдВрдЦреНрдпрд╛ (1-4)ред

рдореЛрдб (рдореЛрдб) - рдкреИрдХреЗрдЯ рдкреНрд░реЗрд╖рдХ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдореЛрдбред рдорд╛рди 0 рд╕реЗ 7 рддрдХ, рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп:

  • 3 - рдЧреНрд░рд╛рд╣рдХ
  • 4 - рд╕рд░реНрд╡рд░
  • 5 - рдкреНрд░рд╕рд╛рд░рдг рдореЛрдб

рдкрд░рдд (рд▓реЗрдпрд░рд┐рдВрдЧ рд╕реНрддрд░) - рд╕рд░реНрд╡рд░ рдФрд░ рд╕рдВрджрд░реНрдн рдШрдбрд╝реА рдХреЗ рдмреАрдЪ рдордзреНрдпрд╡рд░реНрддреА рдкрд░рддреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ (1 - рд╕рд░реНрд╡рд░ рд╕реАрдзреЗ рд╕рдВрджрд░реНрдн рдШрдбрд╝реА рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗрддрд╛ рд╣реИ, 2 - рд╕рд░реНрд╡рд░ рд╕реНрддрд░ 1 рд╡рд╛рд▓реЗ рд╕рд░реНрд╡рд░ рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗрддрд╛ рд╣реИ, рдЖрджрд┐)ред
рдкреВрд▓ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИ рдЬреЛ рд▓рдЧрд╛рддрд╛рд░ рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рдмреАрдЪ рдЕрдзрд┐рдХрддрдо рдЕрдВрддрд░рд╛рд▓ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдПрдирдЯреАрдкреА рдХреНрд▓рд╛рдЗрдВрдЯ рдпрд╣рд╛рдВ рдЙрд╕ рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╡рд╣ рд╕рд░реНрд╡рд░ рд╕реЗ рдкреЛрд▓ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдирдЯреАрдкреА рд╕рд░реНрд╡рд░ рдЙрд╕ рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╡рд╣ рдкреЛрд▓ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реИред рдорд╛рди рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдЗрдирд░реА рд▓рдШреБрдЧрдгрдХ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред
рд╢реБрджреНрдзрддрд╛ (рдкрд░рд┐рд╢реБрджреНрдзрддрд╛) рд╕рд┐рд╕реНрдЯрдо рдШрдбрд╝реА рдХреА рд╕рдЯреАрдХрддрд╛ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИред рдорд╛рди рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдЗрдирд░реА рд▓рдШреБрдЧрдгрдХ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред
рдЬрдбрд╝ рд╡рд┐рд▓рдВрдм (рд╕рд░реНрд╡рд░ рд╡рд┐рд▓рдВрдмрддрд╛) рд╡рд╣ рд╕рдордп рд╣реИ рдЬреЛ рдШрдбрд╝реА рдХреЛ рдПрдирдЯреАрдкреА рд╕рд░реНрд╡рд░ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рд╕реЗрдХрдВрдб рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд-рдмрд┐рдВрджреБ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рдЧрддрд╛ рд╣реИред
рдЬрдбрд╝ рдлреИрд▓рд╛рд╡ (рд╕рд░реНрд╡рд░ рд╕реНрдХреИрдЯрд░) - рд╕реЗрдХрдВрдб рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд-рдмрд┐рдВрджреБ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдирдЯреАрдкреА рд╕рд░реНрд╡рд░ рдШрдбрд╝реА рдХрд╛ рд╕реНрдХреИрдЯрд░ред
рд░реЗрдлрд░реА рдЖрдИрдбреА (рд╕реНрд░реЛрдд рдЖрдИрдбреА) - рдШрдбрд╝реА рдЖрдИрдбреАред рдпрджрд┐ рд╕рд░реНрд╡рд░ рдореЗрдВ рд╕реНрдЯреНрд░реЗрдЯрдо 1 рд╣реИ, рддреЛ рд░реЗрдлрд░реА рдЖрдИрдбреА рдкрд░рдорд╛рдгреБ рдШрдбрд╝реА (4 рдПрдПрд╕рд╕реАрдЖрдИрдЖрдИ рд╡рд░реНрдг) рдХрд╛ рдирд╛рдо рд╣реИред рдпрджрд┐ рд╕рд░реНрд╡рд░ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд░реЗрдлрд░реА рдЖрдИрдбреА рдореЗрдВ рдЗрд╕ рд╕рд░реНрд╡рд░ рдХрд╛ рдкрддрд╛ рд╣реЛрддрд╛ рд╣реИред
рдЕрдВрддрд┐рдо 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 (рдХреНрд▓рд╛рдЗрдВрдЯ рдореЛрдб) рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рд╕рд░реНрд╡рд░, рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдПрдирдЯреАрдкреА рдкреИрдХреЗрдЯ рдореЗрдВ рд╕рднреА рдлрд╝реАрд▓реНрдб рднрд░рддрд╛ рд╣реИ, рдлрд╝реАрд▓реНрдб рдореЗрдВ рдХреЙрдкреА рдХрд░рддрд╛ рд╣реИ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╕реЗ рдореВрд▓реНрдп рд╕рдВрдЪрд╛рд░рд┐рдд, рдЬреЛ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдЖрдпрд╛ рдерд╛ред рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдПрдХ рд░рд╣рд╕реНрдп рд╣реИ рдХрд┐ рдЧреНрд░рд╛рд╣рдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЕрдкрдиреЗ рд╕рдордп рдХрд╛ рдореВрд▓реНрдп рддреБрд░рдВрдд рдХреНрдпреЛрдВ рдирд╣реАрдВ рднрд░ рд╕рдХрддрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛. рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЬрдм рдкреИрдХреЗрдЯ рд╡рд╛рдкрд╕ рдЖрддрд╛ рд╣реИ, рддреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдкрд╛рд╕ 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) рдХреА рдкреБрд░рд╛рдиреА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдЕрдВрдЧреНрд░реЗрдЬ рд╕рдЬреНрдЬрди рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рдорд╛рди рд╣реИ: "рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкрд╛рд╕ рдХрд▓рд╛рдИ рдШрдбрд╝реА рдирд╣реАрдВ рдереА, рд▓реЗрдХрд┐рди рдШрд░ рдкрд░ рдПрдХ рд╕рдЯреАрдХ рджреАрд╡рд╛рд░ рдШрдбрд╝реА рдереА, рдЬрд┐рд╕реЗ рд╡рд╣ рдХрднреА-рдХрднреА рд╣рд╡рд╛ рджреЗрдирд╛ рднреВрд▓ рдЬрд╛рддреЗ рд╣реИрдВред рдПрдХ рджрд┐рди, рд╡рд╣ рдШрдбрд╝реА рдХреЛ рдлрд┐рд░ рд╕реЗ рдЪрд╛рд▓реВ рдХрд░рдирд╛ рднреВрд▓ рдЧрдпрд╛, рд╡рд╣ рдЕрдкрдиреЗ рджреЛрд╕реНрдд рд╕реЗ рдорд┐рд▓рдиреЗ рдЧрдпрд╛, рдЙрд╕рдХреЗ рд╕рд╛рде рд╢рд╛рдо рдмрд┐рддрд╛рдИ рдФрд░ рдЬрдм рд╡рд╣ рдШрд░ рд▓реМрдЯрд╛, рддреЛ рдЙрд╕рдиреЗ рдШрдбрд╝реА рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ред рдпрджрд┐ рдпрд╛рддреНрд░рд╛ рдХрд╛ рд╕рдордп рдкрд╣рд▓реЗ рд╕реЗ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рдерд╛ рддреЛ рдЙрд╕рдиреЗ рдРрд╕рд╛ рдХреИрд╕реЗ рдХрд░ рд▓рд┐рдпрд╛? рдЙрддреНрддрд░ рд╣реИ: тАЬрдШрд░ рдЫреЛрдбрд╝рдХрд░, рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдШрдбрд╝реА рдХреЛ рдШреБрдорд╛рддрд╛ рд╣реИ рдФрд░ рд╣рд╛рдереЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдпрд╛рдж рд░рдЦрддрд╛ рд╣реИред рдХрд┐рд╕реА рджреЛрд╕реНрдд рдХреЗ рдкрд╛рд╕ рдЖрдХрд░ рдореЗрд╣рдорд╛рдиреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдЙрдирдХреЗ рдЖрдиреЗ рдФрд░ рдЬрд╛рдиреЗ рдХрд╛ рд╕рдордп рдиреЛрдЯ рдХрд░ рд▓реЗрддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдЙрд╕реЗ рдкрддрд╛ рдЪрд▓ рд╕рдХреЗрдЧрд╛ рдХрд┐ рд╡рд╣ рдХрд┐рддрдиреА рджреЗрд░ рджреВрд░ рдерд╛ред рдШрд░ рд▓реМрдЯрдХрд░ рдШрдбрд╝реА рджреЗрдЦрдХрд░ рд╡реНрдпрдХреНрддрд┐ рдЕрдкрдиреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЕрд╡рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕рдордп рдореЗрдВ рд╕реЗ рдЙрд╕ рд╕рдордп рдХреЛ рдШрдЯрд╛рдХрд░, рдЬреЛ рдЙрд╕рдиреЗ рдШреВрдордиреЗ рдореЗрдВ рдмрд┐рддрд╛рдпрд╛ рдерд╛, рд╡реНрдпрдХреНрддрд┐ рдХреЛ рд╕рдбрд╝рдХ рдкрд░ рд╡рд╣рд╛рдВ рдФрд░ рд╡рд╛рдкрд╕ рдЖрдиреЗ рдореЗрдВ рдмрд┐рддрд╛рдпрд╛ рдЧрдпрд╛ рд╕рдордп рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИред рд╕рдбрд╝рдХ рдкрд░ рдмрд┐рддрд╛рдП рдЧрдП рд╕рдордп рдХрд╛ рдЖрдзрд╛ рд╕рдордп рдореЗрд╣рдорд╛рдиреЛрдВ рдХреЗ рдЬрд╛рдиреЗ рдХреЗ рд╕рдордп рдореЗрдВ рдЬреЛрдбрд╝рдХрд░, рдЙрд╕реЗ рдШрд░ рдЖрдиреЗ рдХрд╛ рд╕рдордп рдкрддрд╛ рдХрд░рдиреЗ рдФрд░ рдЕрдкрдиреА рдШрдбрд╝реА рдХреА рд╕реБрдЗрдпреЛрдВ рдХреЛ рддрджрдиреБрд╕рд╛рд░ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рддрд╛ рд╣реИред

рдЙрд╕ рд╕рдордп рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ рдЬрдм рд╕рд░реНрд╡рд░ рдЕрдиреБрд░реЛрдз рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛:

  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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ