docs: def double_hash_encode_ngrams(ngrams,   # type: Iterable[str]
                                keys,     # type: Sequence[bytes]
                                ks,       # type: Sequence[int]
                                l,        # type: int
                                encoding  # type: str
                                ):
      # type: (...) -> bitarray
      """ Computes the double hash encoding of the ngrams with the given keys.
  
              Using the method from:
              Schnell, R., Bachteler, T., & Reiher, J. (2011).
              A Novel Error-Tolerant Anonymous Linking Code.
              http://grlc.german-microsimulation.de/wp-content/uploads/2017/05/downloadwp-grlc-2011-02.pdf
  
          :param ngrams: list of n-grams to be encoded
          :param keys: hmac secret keys for md5 and sha1 as bytes
          :param ks: ks[i] is k value to use for ngram[i]
          :param l: length of the output bitarray
          :param encoding: the encoding to use when turning the ngrams to bytes
  
          :return: bitarray of length l with the bits set which correspond to
                   the encoding of the ngrams
      """
      key_sha1, key_md5 = keys
      bf = bitarray(l)
      bf.setall(False)
  
      for m, k in zip(ngrams, ks):
          sha1hm = int(
              hmac.new(key_sha1, m.encode(encoding=encoding), sha1).hexdigest(),
              16) % l
          md5hm = int(
              hmac.new(key_md5, m.encode(encoding=encoding), md5).hexdigest(),
              16) % l
          for i in range(k):
              gi = (sha1hm + i * md5hm) % l
              bf[gi] = 1
      return bf