Ide onye ahịa NTP dị mfe

Ndewo habrausers. Taa, achọrọ m ikwu maka otu esi ede onye ahịa NTP dị mfe nke gị. N'ụzọ bụ isi, mkparịta ụka ahụ ga-atụgharị gaa na nhazi nke ngwugwu yana otu esi ahazi nzaghachi sitere na ihe nkesa NTP. A ga-ede koodu ahụ na Python, n'ihi na, n'echiche nke m, ọ dịghị asụsụ ka mma maka ihe ndị dị otú ahụ. Connoisseurs ga-aṅa ntị na myirịta nke koodu na koodu ntplib - "Enwere m mmụọ nsọ" site na ya.

Yabụ kedu ihe bụ NTP? NTP bụ protocol maka iji sava oge na-ekwurịta okwu. A na-eji protocol a mee ihe n'ọtụtụ igwe ọgbara ọhụrụ. Dịka ọmụmaatụ, ọrụ w32tm na windo.

Enwere ụdị 5 nke protocol NTP na mkpokọta. Nke mbụ, mbipute 0 (1985, RFC958) ka a na-ewere ugbu a na ọ naghịzi arụ ọrụ. Ndị ọhụrụ na-eji ugbu a, 1st (1988, RFC1059), 2nd (1989, RFC1119), 3rd (1992, RFC1305) na 4th (1996, RFC2030). Ụdị 1-4 dakọtara na ibe ha, ha dị iche na algọridim nke sava.

Ụdị ngwugwu

Ide onye ahịa NTP dị mfe

Ngosipụta mwụli elu (Ngosipụta mgbazi) bụ ọnụọgụ na-egosi ịdọ aka na ntị nke abụọ. Pụtara:

  • 0 - enweghị mgbazi
  • 1 - nkeji ikpeazụ nke ụbọchị nwere 61 sekọnd
  • 2 - nkeji ikpeazụ nke ụbọchị nwere sekọnd 59
  • 3 - ọdịda nkesa (oge agwụla)

Nọmba ụdị (nọmba ụdị) - Nọmba ụdị protocol NTP (1-4).

mode (mode) - ụdị ọrụ nke onye na-ezigara ngwugwu. Uru sitere na 0 ruo 7, nke a na-ahụkarị:

  • 3 - onye ahịa
  • 4 - ihe nkesa
  • 5 - ọnọdụ mgbasa ozi

stratum (ọkwa ọkwa) - ọnụ ọgụgụ nke etiti etiti n'etiti ihe nkesa na elekere ntụaka (1 - ihe nkesa na-ewe data ozugbo site na elekere ntụaka, 2 - ihe nkesa na-ewe data site na ihe nkesa na ọkwa 1, wdg).
Pool bụ ọnụọgụ mbinye aka na-anọchite anya oke kacha n'etiti ozi na-esochi. Onye ahịa NTP na-akọwapụta ebe a nkeji oge ọ na-atụ anya ịme ntuli aka nke ihe nkesa, yana sava NTP na-akọwapụta nkeji oge ọ na-atụ anya ka a gụọ ya. Uru ya na ọnụọgụ abụọ logarithm nke sekọnd.
nkenke (nkenke) bụ ọnụọgụ mbinye aka na-egosi izi ezi nke elekere sistemụ. Uru ya na ọnụọgụ abụọ logarithm nke sekọnd.
mgbọrọgwụ igbu oge (Latency server) bụ oge ọ na-ewe maka elekere iru ihe nkesa NTP, dị ka ọnụọgụ nkeji nke sekọnd.
mgbọrọgwụ mgbasa (mgbasa nkesa) - Mgbasa nke elekere ihe nkesa NTP dị ka ọnụọgụ ọnụọgụ nke sekọnd.
Ref id (id id) - elele id. Ọ bụrụ na ihe nkesa ahụ nwere stratum 1, mgbe ahụ ref id bụ aha elekere atomic ( mkpụrụedemede 4 ASCII). Ọ bụrụ na ihe nkesa na-eji ihe nkesa ọzọ, mgbe ahụ ref id nwere adreesị nke ihe nkesa a.
Mpaghara 4 ikpeazụ bụ oge - 32 bits - akụkụ integer, 32 bits - akụkụ nke akụkụ.
Reference - kacha ọhụrụ elekere na ihe nkesa.
Mmalite - oge ezigara ngwugwu ahụ (nke ihe nkesa juputara - karịa na nke dị n'okpuru).
-enweta – oge mgbe ihe nkesa natara ngwugwu.
Ebunye - oge mgbe ezigara ngwugwu ahụ site na ihe nkesa na onye ahịa (nke onye ahịa juputara, karịa na nke dị n'okpuru).

A gaghị atụle mpaghara abụọ ikpeazụ.

Ka anyị dee ngwugwu anyị:

Koodu ngwugwu

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

Iji zipu (na nata) ngwugwu na ihe nkesa, anyị ga-enwe ike ịtụgharị ya ka ọ bụrụ ọtụtụ bytes.
Maka ọrụ a (na tụgharịa), anyị ga-ede ọrụ abụọ - mkpọ () na mkpọpu ():

mkpọ ọrụ

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))

ọrụ ịtọpụ

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

Maka ndị umengwụ, dị ka ngwa - koodu na-atụgharị ngwugwu ahụ n'ime eriri mara mma

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)

Na-eziga ngwugwu na ihe nkesa

Zipu ngwugwu nwere ubi juputara na ihe nkesa version, mode и Ebunye. The Ebunye ị ga-ezipụta oge dị ugbu a na igwe mpaghara (ọnụọgụ nke sekọnd kemgbe Jenụwarị 1, 1900), ụdị - nke ọ bụla nke 1-4, ọnọdụ - 3 (ọnọdụ ndị ahịa).

Ihe nkesa ahụ, mgbe ọ natara arịrịọ ahụ, jupụta na mpaghara niile dị na ngwugwu NTP, na-edegharị n'ọhịa Mmalite uru si Ebunye, nke batara na arịrịọ ahụ. Ọ bụụrụ m ihe omimi ihe kpatara na onye ahịa enweghị ike mejupụta uru nke oge ya n'ọhịa ozugbo Mmalite. N'ihi ya, mgbe ngwugwu ahụ lọghachiri, onye ahịa ahụ nwere ụkpụrụ oge 4 - oge ezigara arịrịọ ahụ (Mmalite), oge ihe nkesa natara arịrịọ (-enweta), oge ihe nkesa zigara nzaghachi (Ebunye) na oge nnata nke nzaghachi nke onye ahịa - Bilie (ọ bụghị na ngwugwu). Site na ụkpụrụ ndị a anyị nwere ike ịtọ oge kwesịrị ekwesị.

Koodu izipu na nnata ngwugwu

# 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)

Na-ahazi data sitere na sava ahụ

Ịhazi data sitere na ihe nkesa ahụ yiri omume nke nwa amadi Bekee sitere na nsogbu ochie nke Raymond M. Smullyan (1978): "Otu nwoke enweghị elekere aka, ma enwere elekere mgbidi ziri ezi n'ụlọ, nke ọ na-echefu mgbe ụfọdụ. iji ifufe. Otu ụbọchị, ebe ọ chefuworo ịgbanye elekere ya ọzọ, ọ gara leta enyi ya, soro ya nọrọ ná mgbede, mgbe ọ lọtara, o jisiri ike dobe elekere nke ọma. Olee otú o si mee nke a ma ọ bụrụ na a mataghị oge njem ahụ n’oge mbụ? Azịza ya bụ: “Mgbe mmadụ si n’ụlọ pụọ, ọ na-ekuli elekere wee cheta ọnọdụ aka ya. N'ịbụ onye na-abịakwute enyi ma hapụ ndị ọbịa ahụ, ọ na-edeba oge ọbịbịa na ọpụpụ ya. Nke a na-enye ya ohere ịchọpụta ogologo oge ọ gara nleta. Ịlaghachi n'ụlọ ma na-ele elekere anya, mmadụ na-ekpebi oge ọ ga-anọ. N'ịwepụ n'oge a ọ nọrọ na-eleta, onye ahụ na-achọpụta oge ọ nọrọ n'okporo ụzọ ahụ ma laghachi. Site n'ịgbakwunye ọkara nke oge a na-etinye n'okporo ụzọ na oge ịhapụ ndị ọbịa, ọ na-enweta ohere iji chọpụta oge ọbịbịa n'ụlọ ma gbanwee aka nke elekere ya n'ụzọ kwesịrị ekwesị.

Chọta oge ihe nkesa na-arụ ọrụ na arịrịọ:

  1. Ịchọta oge njem ngwungwu site n'aka onye ahịa gaa na nkesa: ((Bịa - Mmalite) - (Nnyefe - Nnata)) / 2
  2. Chọta ihe dị iche n'etiti onye ahịa na oge nkesa:
    Nnata - Mmalite - ((Bịa - Mmalite) - (Nnyefe - Nnata)) / 2 =
    2 * Nnata - 2 * Mmalite - bịarutere + Mmalite + Nyefee - Nnata =
    Anata - Mmalite - Bia + Nyefee

Anyị na-agbakwunye uru natara na oge mpaghara ma nwee obi ụtọ ndụ.

Nsonaazụ

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)

Bara uru ngalaba.

isi: www.habr.com

Tinye a comment