ruby 符合RFC 5322的消息ID生成器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby 符合RFC 5322的消息ID生成器相关的知识,希望对你有一定的参考价值。

require "socket"

class MessageID
  UnsupportedFormatException = Class.new(StandardError)

  MESSAGE_ID_FORMAT = "<%s.%s.%s%s@%s>"
  STAMP_FIELD_FORMAT = "%Y%m%d%H%M%S%6N"

  def initialize(*ident)
    @ident = ident.compact.flatten
    @ident << Random.rand(999_999_999) if @ident.empty?
  end

  def id(format=:short)
    raise(UnsupportedFormatException) unless %I{ short long }.include?(format)
    sprintf(MESSAGE_ID_FORMAT, *fields(format == :short))
  end
  alias :to_str :id
  alias :to_s :id

  private

  def timestamp
    @timestamp ||= Time.now.utc
  end

  def random_id
    @random_id ||= Random.rand(999_999_999)
  end

  def fields(shorten)
    values = [
      timestamp.strftime(STAMP_FIELD_FORMAT).to_i,
      (shorten ? base36ify(@ident) : @ident).join("."),
      Process.pid,
      random_id,
      Socket.gethostname
    ]
    shorten ? base36ify(values) : values
  end

  def base36ify(fields)
    fields.collect { |v| v.is_a?(Integer) ? v.to_s(36) : v }
  end
end

puts MessageID.new  #=> <493bxydx7qi5h.52p76a.10bvae8w0@host.local>

5.times { puts MessageID.new }
#=> <493bxydx7qi5h.52p76a.10bvae8w0@host.local>
#   <493bxydx7qi62.22u8jg.10bvcz4bld@host.local>
#   <493bxydx7qi6m.w829m.10bv9e8v5f@host.local>
#   <493bxydx7qi73.batkan.10bv5cx20x@host.local>
#   <493bxydx7qi7j.eg3gvy.10bvaa6h31@host.local>

msgid = MessageID.new(20_345_678, 23_456, 23, 234)

puts msgid              #=> <493bxydqj4y6n.c42tq.i3k.n.6i.zro9a3djq@host.local>
puts msgid.to_s(:long)  #=> <20150302113621373199.20345678.23456.23.234.46356561149270@host.local>
require "date"

class MessageID
  module Decode
    STAMP_FIELD_FORMAT = "%Y%m%d%H%M%S%N"

    def self.decode(id)
      user, host = id.split("@")
      parts = user.split(".").map { |part| part.to_i(36) }
      stamp, ident = parts.shift, []
      while (parts.length > 1) do ident << parts.shift; end
      counter = parts.last
      stamp = DateTime.strptime(stamp.to_s, STAMP_FIELD_FORMAT)

      {
        stamp:   stamp.strftime("%Y-%m-%d %H:%M:%S.%6N"),
        ident:   ident,
        counter: counter,
        host:    host
      }
    end
  end
end

ids = %w{
  493c39w9zx13q.b4tn3y.2ato@437783-daemon6.lon3.whitelabeldating.com
  493c39wjpvh8y.xgp16n.85h17@428180-daemon5.lon3.whitelabeldating.com
  493c39wtz5dnq.qgja3v.tyz1t@370845-daemon4.lon3.whitelabeldating.com
  493c39x0su3js.rz53nu.1hx9k@370843-daemon2.lon3.whitelabeldating.com
}

ids.each { |id| p MessageID::Decode.decode(id) }

以上是关于ruby 符合RFC 5322的消息ID生成器的主要内容,如果未能解决你的问题,请参考以下文章

根据 RFC5322 和 https://en.wikipedia.org/wiki/Email_address 验证电子邮件 ID

对 SMTP 消息 ID 的限制?

符合RFC的电子邮件地址验证程序

根据 RFC5321/RFC5322 对电子邮件地址进行正则表达式验证

正则表达式,获取电子邮件日期头字段的所有部分

带有特殊字符的电子邮件被拒绝 - RFC-6532 和“quoted-printable”