เจ‡เฉฑเจ• เจธเจงเจพเจฐเจจ NTP เจ•เจฒเจพเจ‡เฉฐเจŸ เจฒเจฟเจ–เจฃเจพ

เจนเฉˆเจฒเฉ‹, Habrausers. เจ…เฉฑเจœ เจฎเฉˆเจ‚ เจ‡เจธ เจฌเจพเจฐเฉ‡ เจ—เฉฑเจฒ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเจพ เจนเจพเจ‚ เจ•เจฟ เจคเฉเจนเจพเจกเฉ‡ เจ†เจชเจฃเฉ‡ เจธเจงเจพเจฐเจจ NTP เจ•เจฒเจพเจ‡เฉฐเจŸ เจจเฉ‚เฉฐ เจ•เจฟเจตเฉ‡เจ‚ เจฒเจฟเจ–เจฃเจพ เจนเฉˆ. เจ…เจธเจฒ เจตเจฟเฉฑเจš, เจ—เฉฑเจฒเจฌเจพเจค เจชเฉˆเจ•เฉ‡เจŸ เจฆเฉ€ เจฌเจฃเจคเจฐ เจ…เจคเฉ‡ NTP เจธเจฐเจตเจฐ เจคเฉ‹เจ‚ เจœเจตเจพเจฌ เจฆเฉ€ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจ•เจฐเจจ เจฆเฉ€ เจตเจฟเจงเฉ€ เจตเฉฑเจฒ เจฎเฉเฉœเฉ‡เจ—เฉ€เฅค เจ•เฉ‹เจก เจชเจพเจˆเจฅเจจ เจตเจฟเฉฑเจš เจฒเจฟเจ–เจฟเจ† เจœเจพเจตเฉ‡เจ—เจพ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เจน เจฎเฉˆเจจเฉ‚เฉฐ เจœเจพเจชเจฆเจพ เจนเฉˆ เจ•เจฟ เจ…เจœเจฟเจนเฉ€เจ†เจ‚ เจšเฉ€เจœเจผเจพเจ‚ เจฒเจˆ เจ•เฉ‹เจˆ เจฌเจฟเจนเจคเจฐ เจญเจพเจธเจผเจพ เจจเจนเฉ€เจ‚ เจนเฉˆเฅค เจ•เฉŒเจจเฉ‹เจ‡เจธเจฐเจœเจผ ntplib เจ•เฉ‹เจก เจฆเฉ‡ เจจเจพเจฒ เจ•เฉ‹เจก เจฆเฉ€ เจธเจฎเจพเจจเจคเจพ เจจเฉ‚เฉฐ เจจเฉ‹เจŸ เจ•เจฐเจจเจ—เฉ‡ - เจฎเฉˆเจ‚ เจ‡เจธ เจคเฉ‹เจ‚ "เจชเฉเจฐเฉ‡เจฐเจฟเจค" เจธเฉ€เฅค

เจคเจพเจ‚ เจ…เจธเจฒ เจตเจฟเฉฑเจš NTP เจ•เฉ€ เจนเฉˆ? NTP เจธเจนเฉ€ เจธเจฎเฉ‡เจ‚ เจฆเฉ‡ เจธเจฐเจตเจฐเจพเจ‚ เจจเจพเจฒ เจชเจฐเจธเจชเจฐ เจชเฉเจฐเจญเจพเจต เจฒเจˆ เจ‡เฉฑเจ• เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจนเฉˆเฅค เจ‡เจน เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจฌเจนเฉเจค เจธเจพเจฐเฉ€เจ†เจ‚ เจ†เจงเฉเจจเจฟเจ• เจฎเจธเจผเฉ€เจจเจพเจ‚ เจตเจฟเฉฑเจš เจตเจฐเจคเจฟเจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจตเจฟเฉฐเจกเฉ‹เจœเจผ เจตเจฟเฉฑเจš w32tm เจธเฉ‡เจตเจพเฅค

เจ•เฉเฉฑเจฒ เจฎเจฟเจฒเจพ เจ•เฉ‡ NTP เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจฆเฉ‡ 5 เจธเฉฐเจธเจ•เจฐเจฃ เจนเจจเฅค เจชเจนเจฟเจฒเจพ, เจธเฉฐเจธเจ•เจฐเจฃ 0 (1985, RFC958)), เจตเจฐเจคเจฎเจพเจจ เจตเจฟเฉฑเจš เจชเฉเจฐเจพเจฃเจพ เจฎเฉฐเจจเจฟเจ† เจœเจพเจ‚เจฆเจพ เจนเฉˆเฅค เจนเฉเจฃ เจจเจตเฉ‡เจ‚ เจตเจฐเจคเฉ‡ เจœเจพเจ‚เจฆเฉ‡ เจนเจจ, เจชเจนเจฟเจฒเจพ (1, RFC1988), เจฆเฉ‚เจœเจพ (1059, RFC2), เจคเฉ€เจœเจพ (1989, RFC1119) เจ…เจคเฉ‡ เจšเฉŒเจฅเจพ (3, RFC1992)เฅค เจธเฉฐเจธเจ•เจฐเจฃ 1305-4 เจ‡เฉฑเจ• เจฆเฉ‚เจœเฉ‡ เจฆเฉ‡ เจ…เจจเฉเจ•เฉ‚เจฒ เจนเจจ; เจ‰เจน เจธเจฟเจฐเจซ เจธเจฐเจตเจฐ เจ“เจชเจฐเฉ‡เจธเจผเจจ เจเจฒเจ—เฉ‹เจฐเจฟเจฆเจฎ เจตเจฟเฉฑเจš เจตเฉฑเจ–เจฐเฉ‡ เจนเจจเฅค

เจชเฉˆเจ•เฉ‡เจœ เจซเจพเจฐเจฎเฉˆเจŸ

เจ‡เฉฑเจ• เจธเจงเจพเจฐเจจ NTP เจ•เจฒเจพเจ‡เฉฐเจŸ เจฒเจฟเจ–เจฃเจพ

เจฒเฉ€เจช เจธเฉ‚เจšเจ• (เจธเฉเจงเจพเจฐ เจธเฉ‚เจšเจ•) - เจ‡เฉฑเจ• เจธเฉฐเจ–เจฟเจ† เจœเฉ‹ เจคเจพเจฒเจฎเฉ‡เจฒ เจธเฉˆเจ•เจฟเฉฐเจก เจฌเจพเจฐเฉ‡ เจšเฉ‡เจคเจพเจตเจจเฉ€ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเฉ€ เจนเฉˆเฅค เจญเจพเจต:

  • 0 - เจ•เฉ‹เจˆ เจธเฉเจงเจพเจฐ เจจเจนเฉ€เจ‚
  • 1 - เจฆเจฟเจจ เจฆเฉ‡ เจ†เจ–เจฐเฉ€ เจฎเจฟเฉฐเจŸ เจตเจฟเฉฑเจš 61 เจธเจ•เจฟเฉฐเจŸ เจนเฉเฉฐเจฆเฉ‡ เจนเจจ
  • 2 - เจฆเจฟเจจ เจฆเฉ‡ เจ†เจ–เจฐเฉ€ เจฎเจฟเฉฐเจŸ เจตเจฟเฉฑเจš 59 เจธเจ•เจฟเฉฐเจŸ เจนเฉเฉฐเจฆเฉ‡ เจนเจจ
  • 3 - เจธเจฐเจตเจฐ เจ–เจฐเจพเจฌเฉ€ (เจธเจฎเจพเจ‚ เจธเจฎเจ•เจพเจฒเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ)

เจตเจฐเจœเจจ เจจเฉฐเจฌเจฐ (เจตเจฐเจœเจจ เจจเฉฐเจฌเจฐ) โ€“ NTP เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจตเจฐเจœเจจ เจจเฉฐเจฌเจฐ (1-4)เฅค

เจฎเฉ‹เจก (เจฎเฉ‹เจก) - เจชเฉˆเจ•เฉ‡เจŸ เจญเฉ‡เจœเจฃ เจตเจพเจฒเฉ‡ เจฆเจพ เจ“เจชเจฐเฉ‡เจŸเจฟเฉฐเจ— เจฎเฉ‹เจกเฅค 0 เจคเฉ‹เจ‚ 7 เจคเฉฑเจ• เจฆเจพ เจฎเฉเฉฑเจฒ, เจธเจญ เจคเฉ‹เจ‚ เจ†เจฎ:

  • 3 - เจ—เจพเจนเจ•
  • 4 - เจธเจฐเจตเจฐ
  • 5 - เจชเฉเจฐเจธเจพเจฐเจฃ เจฎเฉ‹เจก

เจธเจŸเฉเจฐเฉˆเจŸเจฎ (เจฒเฉ‡เจ…เจฐเจฟเฉฐเจ— เจชเฉฑเจงเจฐ) - เจธเจฐเจตเจฐ เจ…เจคเฉ‡ เจธเฉฐเจฆเจฐเจญ เจ˜เฉœเฉ€ เจฆเฉ‡ เจตเจฟเจšเจ•เจพเจฐ เจตเจฟเจšเจ•เจพเจฐเจฒเฉ‡ เจฒเฉ‡เจ…เจฐเจพเจ‚ เจฆเฉ€ เจ—เจฟเจฃเจคเฉ€ (1 - เจธเจฐเจตเจฐ เจนเจตเจพเจฒเจพ เจ˜เฉœเฉ€ เจคเฉ‹เจ‚ เจธเจฟเฉฑเจงเจพ เจกเจพเจŸเจพ เจฒเฉˆเจ‚เจฆเจพ เจนเฉˆ, 2 - เจธเจฐเจตเจฐ เจฒเฉ‡เจ…เจฐ 1, เจ†เจฆเจฟ เจตเจพเจฒเฉ‡ เจธเจฐเจตเจฐ เจคเฉ‹เจ‚ เจกเจพเจŸเจพ เจฒเฉˆเจ‚เจฆเจพ เจนเฉˆ)เฅค
เจชเฉ‚เจฒ เจฒเจ—เจพเจคเจพเจฐ เจธเฉเจจเฉ‡เจนเจฟเจ†เจ‚ เจตเจฟเจšเจ•เจพเจฐ เจตเฉฑเจง เจคเฉ‹เจ‚ เจตเฉฑเจง เจ…เฉฐเจคเจฐเจพเจฒ เจจเฉ‚เฉฐ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเจพ เจ‡เฉฑเจ• เจนเจธเจคเจพเจ–เจฐเจฟเจค เจชเฉ‚เจฐเจจ เจ…เฉฐเจ• เจนเฉˆเฅค NTP เจ•เจฒเจพเจ‡เฉฐเจŸ เจ‡เฉฑเจฅเฉ‡ เจ…เฉฐเจคเจฐเจพเจฒ เจจเฉ‚เฉฐ เจจเจฟเจฐเจงเจพเจฐเจฟเจค เจ•เจฐเจฆเจพ เจนเฉˆ เจœเจฟเจธ 'เจคเฉ‡ เจ‡เจน เจธเจฐเจตเจฐ เจจเฉ‚เฉฐ เจชเฉ‹เจฒ เจ•เจฐเจจ เจฆเฉ€ เจ‰เจฎเฉ€เจฆ เจ•เจฐเจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ NTP เจธเจฐเจตเจฐ เจ‰เจธ เจ…เฉฐเจคเจฐเจพเจฒ เจจเฉ‚เฉฐ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐเจฆเจพ เจนเฉˆ เจœเจฟเจธ 'เจคเฉ‡ เจ‡เจน เจชเฉ‹เจฒ เจ•เฉ€เจคเฉ‡ เจœเจพเจฃ เจฆเฉ€ เจ‰เจฎเฉ€เจฆ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจฎเฉเฉฑเจฒ เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจฆเฉ‡ เจฌเจพเจˆเจจเจฐเฉ€ เจฒเจ˜เฉ‚เจ—เจฃเจ• เจฆเฉ‡ เจฌเจฐเจพเจฌเจฐ เจนเฉˆเฅค
เจธเจผเฉเฉฑเจงเจคเจพ (เจธเจผเฉเฉฑเจงเจคเจพ) เจ‡เฉฑเจ• เจนเจธเจคเจพเจ–เจฐเจฟเจค เจชเฉ‚เจฐเจจ เจ…เฉฐเจ• เจนเฉˆ เจœเฉ‹ เจธเจฟเจธเจŸเจฎ เจ•เจฒเจพเจ• เจฆเฉ€ เจธเจผเฉเฉฑเจงเจคเจพ เจจเฉ‚เฉฐ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจฎเฉเฉฑเจฒ เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจฆเฉ‡ เจฌเจพเจˆเจจเจฐเฉ€ เจฒเจ˜เฉ‚เจ—เจฃเจ• เจฆเฉ‡ เจฌเจฐเจพเจฌเจฐ เจนเฉˆเฅค
เจฐเฉ‚เจŸ เจฆเฉ‡เจฐเฉ€ (เจธเจฐเจตเจฐ เจฆเฉ‡เจฐเฉ€) - เจ˜เฉœเฉ€ เจฐเฉ€เจกเจฟเฉฐเจ— เจจเฉ‚เฉฐ NTP เจธเจฐเจตเจฐ เจคเฉฑเจ• เจชเจนเฉเฉฐเจšเจฃ เจฒเจˆ เจธเจฎเจพเจ‚ เจฒเฉฑเจ—เจฆเจพ เจนเฉˆ, เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจฆเฉ€ เจ‡เฉฑเจ• เจจเจฟเจธเจผเจšเจฟเจค-เจชเฉเจ†เจ‡เฉฐเจŸ เจธเฉฐเจ–เจฟเจ† เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจšเฅค
เจฐเฉ‚เจŸ เจซเฉˆเจฒเจพเจ… (เจธเจฐเจตเจฐ เจซเฉˆเจฒเจพเจ…) - เจ‡เฉฑเจ• เจจเจฟเจธเจผเจšเจค เจฌเจฟเฉฐเจฆเฉ‚ เจฆเฉ‡ เจจเจพเจฒ เจ•เจˆ เจธเจ•เจฟเฉฐเจŸเจพเจ‚ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš NTP เจธเจฐเจตเจฐ เจ•เจฒเจพเจ• เจฐเฉ€เจกเจฟเฉฐเจ— เจฆเจพ เจซเฉˆเจฒเจฃเจพเฅค
เจฐเฉˆเจซเจฐเฉ€ เจ†เจˆ.เจกเฉ€ (เจธเจฐเฉ‹เจค เจชเจ›เจพเจฃเจ•เจฐเจคเจพ) - เจ˜เฉœเฉ€ เจ†เจˆ.เจกเฉ€. เจœเฉ‡เจ•เจฐ เจธเจฐเจตเจฐ เจตเจฟเฉฑเจš เจธเจŸเฉเจฐเฉˆเจŸเจฎ 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

เจธเจฐเจตเจฐ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจชเฉˆเจ•เฉ‡เจŸ เจญเฉ‡เจœเจฃ (เจ…เจคเฉ‡ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ) เจฒเจˆ, เจธเจพเจจเฉ‚เฉฐ เจ‡เจธเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจฌเจพเจˆเจŸ เจเจฐเฉ‡ เจตเจฟเฉฑเจš เจฌเจฆเจฒเจฃ เจฆเฉ‡ เจฏเฉ‹เจ— เจนเฉ‹เจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆเฅค
เจ‡เจธ (เจ…เจคเฉ‡ เจ‰เจฒเจŸ) เจ•เจพเจฐเจตเจพเจˆ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจฆเฉ‹ เจซเฉฐเจ•เจธเจผเจจ เจฒเจฟเจ–เจพเจ‚เจ—เฉ‡ - 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)

เจธเจฐเจตเจฐ เจจเฉ‚เฉฐ เจชเฉˆเจ•เฉ‡เจœ เจญเฉ‡เจœเจฟเจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ

เจญเจฐเฉ‡ เจนเฉ‹เจ เจ–เฉ‡เจคเจฐเจพเจ‚ เจตเจพเจฒเจพ เจ‡เฉฑเจ• เจชเฉˆเจ•เฉ‡เจŸ เจธเจฐเจตเจฐ เจจเฉ‚เฉฐ เจญเฉ‡เจœเจฟเจ† เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ เจตเจฐเจœเจจ, เจฎเฉ‹เจก ะธ เจชเฉเจฐเจธเจพเจฐเจฟเจค. The เจชเฉเจฐเจธเจพเจฐเจฟเจค เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจฅเจพเจจเจ• เจฎเจธเจผเฉ€เจจ 'เจคเฉ‡ เจฎเฉŒเจœเฉ‚เจฆเจพ เจธเจฎเจพเจ‚ (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) เจฆเฉ€ เจชเฉเจฐเจพเจฃเฉ€ เจธเจฎเฉฑเจธเจฟเจ† เจคเฉ‹เจ‚ เจ…เฉฐเจ—เจฐเฉ‡เจœเจผ เจธเฉฑเจœเจฃ เจฆเฉ€เจ†เจ‚ เจ•เจพเจฐเจตเจพเจˆเจ†เจ‚ เจฆเฉ‡ เจธเจฎเจพเจจ เจนเฉˆ: "เจ‡เฉฑเจ• เจ†เจฆเจฎเฉ€ เจ•เฉ‹เจฒ เจ—เฉเฉฑเจŸ เจ˜เฉœเฉ€ เจจเจนเฉ€เจ‚ เจธเฉ€, เจชเจฐ เจ˜เจฐ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจธเจนเฉ€ เจ•เฉฐเจง เจ˜เฉœเฉ€ เจธเฉ€, เจœเจฟเจธเจจเฉ‚เฉฐ เจ‰เจน เจ•เจˆ เจตเจพเจฐ เจญเฉเฉฑเจฒ เจœเจพเจ‚เจฆเจพ เจธเฉ€เฅค เจนเจตเจพ เจจเฉ‚เฉฐ. เจ‡เฉฑเจ• เจฆเจฟเจจ, เจ†เจชเจฃเฉ€ เจ˜เฉœเฉ€ เจจเฉ‚เฉฐ เจฆเฉเจฌเจพเจฐเจพ เจšเจฒเจพเจ‰เจฃเจพ เจญเฉเฉฑเจฒ เจ—เจฟเจ†, เจ‰เจน เจ†เจชเจฃเฉ‡ เจฆเฉ‹เจธเจค เจจเฉ‚เฉฐ เจฎเจฟเจฒเจฃ เจšเจฒเจพ เจ—เจฟเจ†, เจธเจผเจพเจฎ เจ‰เจธ เจจเจพเจฒ เจฌเจฟเจคเจพเจˆ, เจ…เจคเฉ‡ เจœเจฆเฉ‹เจ‚ เจ‰เจน เจ˜เจฐ เจตเจพเจชเจธ เจ†เจ‡เจ†, เจคเจพเจ‚ เจ‰เจธเจจเฉ‡ เจ˜เฉœเฉ€ เจจเฉ‚เฉฐ เจธเจนเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจธเฉˆเฉฑเจŸ เจ•เฉ€เจคเจพเฅค เจœเฉ‡ เจฏเจพเจคเจฐเจพ เจฆเจพ เจธเจฎเจพเจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจชเจคเจพ เจจเจนเฉ€เจ‚ เจธเฉ€ เจคเจพเจ‚ เจ‰เจธเจจเฉ‡ เจ…เจœเจฟเจนเจพ เจ•เจฟเจตเฉ‡เจ‚ เจ•เฉ€เจคเจพ? เจœเจตเจพเจฌ เจนเฉˆ: โ€œเจ˜เจฐ เจ›เฉฑเจกเจฃ เจตเฉ‡เจฒเฉ‡, เจ‡เฉฑเจ• เจตเจฟเจ…เจ•เจคเฉ€ เจ†เจชเจฃเฉ€ เจ˜เฉœเฉ€ เจจเฉ‚เฉฐ เจนเจตเจพ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจฏเจพเจฆ เจฐเฉฑเจ–เจฆเจพ เจนเฉˆ เจ•เจฟ เจนเฉฑเจฅ เจ•เจฟเจธ เจธเจฅเจฟเจคเฉ€ เจตเจฟเฉฑเจš เจนเจจเฅค เจ•เจฟเจธเฉ‡ เจฆเฉ‹เจธเจค เจ•เฉ‹เจฒ เจ† เจ•เฉ‡ เจ…เจคเฉ‡ เจฎเจนเจฟเจฎเจพเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ›เฉฑเจก เจ•เฉ‡, เจ‰เจน เจ†เจชเจฃเฉ‡ เจ†เจ‰เจฃ เจ…เจคเฉ‡ เจœเจพเจฃ เจฆเจพ เจธเจฎเจพเจ‚ เจจเฉ‹เจŸ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจ‡เจน เจ‰เจธเจจเฉ‚เฉฐ เจ‡เจน เจชเจคเจพ เจฒเจ—เจพเจ‰เจฃ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ เจ•เจฟ เจ‰เจน เจ•เจฟเฉฐเจจเฉ‡ เจธเจฎเฉ‡เจ‚ เจฒเจˆ เจฎเฉเจฒเจพเจ•เจพเจค เจ•เจฐ เจฐเจฟเจนเจพ เจธเฉ€เฅค เจ˜เจฐ เจตเจพเจชเจธ เจ† เจ•เฉ‡ เจ…เจคเฉ‡ เจ˜เฉœเฉ€ เจจเฉ‚เฉฐ เจฆเฉ‡เจ– เจ•เฉ‡, เจ‡เฉฑเจ• เจตเจฟเจ…เจ•เจคเฉ€ เจ†เจชเจฃเฉ€ เจ—เฉˆเจฐเจนเจพเจœเจผเจฐเฉ€ เจฆเฉ€ เจฎเจฟเจ†เจฆ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐเจฆเจพ เจนเฉˆ. เจ‡เจธ เจธเจฎเฉ‡เจ‚ เจคเฉ‹เจ‚ เจ˜เจŸเจพ เจ•เฉ‡ เจ‰เจธ เจจเฉ‡ เจฎเจฟเจฒเจฃ เจฒเจˆ เจฌเจฟเจคเจพเจ‡เจ† เจธเจฎเจพเจ‚, เจ‡เฉฑเจ• เจตเจฟเจ…เจ•เจคเฉ€ เจ‰เฉฑเจฅเฉ‡ เจ…เจคเฉ‡ เจตเจพเจชเจธ เจฏเจพเจคเจฐเจพ เจ•เจฐเจจ เจตเจฟเฉฑเจš เจฌเจฟเจคเจพเจ เจธเจฎเฉ‡เจ‚ เจฆเจพ เจชเจคเจพ เจฒเจ—เจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจฎเจนเจฟเจฎเจพเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ›เฉฑเจกเจฃ เจฆเฉ‡ เจธเจฎเฉ‡เจ‚ เจตเจฟเฉฑเจš เจธเฉœเจ• 'เจคเฉ‡ เจฌเจฟเจคเจพเจ เจ…เฉฑเจงเฉ‡ เจธเจฎเฉ‡เจ‚ เจจเฉ‚เฉฐ เจœเฉ‹เฉœ เจ•เฉ‡, เจ‰เจธเจจเฉ‚เฉฐ เจ˜เจฐ เจชเจนเฉเฉฐเจšเจฃ เจฆเจพ เจธเจฎเจพเจ‚ เจชเจคเจพ เจ•เจฐเจจ เจ…เจคเฉ‡ เจ‰เจธ เจ…เจจเฉเจธเจพเจฐ เจ†เจชเจฃเฉ€ เจ˜เฉœเฉ€ เจฆเฉ‡ เจนเฉฑเจฅเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจจเฉเจ•เฉ‚เจฒ เจ•เจฐเจจ เจฆเจพ เจฎเฉŒเจ•เจพ เจฎเจฟเจฒเจฆเจพ เจนเฉˆเฅค

เจธเจฐเจตเจฐ เจฆเฉเจ†เจฐเจพ เจ‡เฉฑเจ• เจฌเฉ‡เจจเจคเฉ€ 'เจคเฉ‡ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเจพ เจธเจฎเจพเจ‚ เจฒเฉฑเจญเฉ‹:

  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

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹