bjjb / chromaprint.js

A JavaScript implementation of AcoustID Chromaprint
GNU Lesser General Public License v3.0
61 stars 17 forks source link

Compare two fingerprint #3

Closed loretoparisi closed 6 years ago

loretoparisi commented 6 years ago

I have found this algorithm some where to compare two Chromaprint fingerprint:

def compare_b64_fingerprint(a,b):
    'returns inverse bit error rate in percent'
    a = b64decode(a)
    b = b64decode(b)

    matching_bits  = 0
    different_bits = 0

    if len(b) != len(a):
        # trim to shortest
        shortest = min(len(a),len(b))
        longest  = max(len(a),len(b))

        a = a[:shortest]
        b = b[:shortest]

        # extra bits count as different
        different_bits = 8*(longest-shortest)

    for i in range( len(a) ):
        byte_a = ord( a[i:i+1] )
        byte_b = ord( b[i:i+1] )

        for x in range(8):
            bit_a = byte_a >> x & 1
            bit_b = byte_b >> x & 1

            if (bit_a == bit_b):
                matching_bits  +=1
            else:
                different_bits +=1

    total_bits = different_bits + matching_bits

    return float(matching_bits) / float(total_bits)

I would like to know if in this javascript implementation there is such an algorithm

bjjb commented 6 years ago

@loretoparisi, that's currently outside the scope of the project. Currently... but I'd like to see it added! If you wanna add a compare.coffee file, I'll be happy to review the PR!

loretoparisi commented 6 years ago

@bjjb going to add a PR. I have first converted to JS and the to Coffee:

var compare_b64_fingerprint, ord;

ord = function(string) {
  var code, hi, low, str;
  str = string + '';
  code = str.charCodeAt(0);
  if (code >= 0xD800 && code <= 0xDBFF) {
    hi = code;
    if (str.length === 1) {
      return code;
    }
    low = str.charCodeAt(1);
    return (hi - 0xD800) * 0x400 + low - 0xDC00 + 0x10000;
  }
  if (code >= 0xDC00 && code <= 0xDFFF) {
    return code;
  }
  return code;
};

compare_b64_fingerprint = function(a, b) {
  'returns inverse bit error rate in percent';
  var bit_a, bit_b, byte_a, byte_b, different_bits, i, longest, matching_bits, shortest, total_bits, x;
  a = b64decode(a);
  b = b64decode(b);
  matching_bits = 0;
  different_bits = 0;
  if (b.length !== a.length) {
    shortest = min(len(a), len(b));
    longest = max(len(a), len(b));
    a = a.slice(0, shortest);
    b = b.slice(0, shortest);
    different_bits = 8 * (longest - shortest);
  }
  i = 0;
  while (i < a.length) {
    byte_a = ord(a.slice(i, i + 1));
    byte_b = ord(b.slice(i, i + 1));
    x = 0;
    while (x < 8) {
      bit_a = byte_a >> x & 1;
      bit_b = byte_b >> x & 1;
      if (bit_a === bit_b) {
        matching_bits += 1;
      } else {
        different_bits += 1;
      }
      x++;
    }
    i++;
  }
  total_bits = different_bits + matching_bits;
  return float(matching_bits) / float(total_bits);
};

// ---
// generated by coffee-script 1.9.2
ord = (string) ->
  #  discuss at: http://locutus.io/php/ord/
  # original by: Kevin van Zonneveld (http://kvz.io)
  # bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
  # improved by: Brett Zamir (http://brett-zamir.me)
  #    input by: incidence
  #   example 1: ord('K')
  #   returns 1: 75
  #   example 2: ord('\uD800\uDC00'); // surrogate pair to create a single Unicode character
  #   returns 2: 65536
  str = string + ''
  code = str.charCodeAt(0)
  if code >= 0xD800 and code <= 0xDBFF
    # High surrogate (could change last hex to 0xDB7F to treat
    # high private surrogates as single characters)
    hi = code
    if str.length == 1
      # This is just a high surrogate with no following low surrogate,
      # so we return its value;
      return code
      # we could also throw an error as it is not a complete character,
      # but someone may want to know
    low = str.charCodeAt(1)
    return (hi - 0xD800) * 0x400 + low - 0xDC00 + 0x10000
  if code >= 0xDC00 and code <= 0xDFFF
    # Low surrogate
    # This is just a low surrogate with no preceding high surrogate,
    # so we return its value;
    return code
    # we could also throw an error as it is not a complete character,
    # but someone may want to know
  code

compare_b64_fingerprint = (a, b) ->
  'returns inverse bit error rate in percent'
  a = b64decode(a)
  b = b64decode(b)
  matching_bits = 0
  different_bits = 0
  if b.length != a.length
    # trim to shortest
    shortest = min(len(a), len(b))
    longest = max(len(a), len(b))
    a = a.slice(0, shortest)
    b = b.slice(0, shortest)
    # extra bits count as different
    different_bits = 8 * (longest - shortest)
  i = 0
  while i < a.length
    byte_a = ord(a.slice(i, i + 1))
    byte_b = ord(b.slice(i, i + 1))
    x = 0
    while x < 8
      bit_a = byte_a >> x & 1
      bit_b = byte_b >> x & 1
      if bit_a == bit_b
        matching_bits += 1
      else
        different_bits += 1
      x++
    i++
  total_bits = different_bits + matching_bits
  float(matching_bits) / float(total_bits)

# ---
# generated by js2coffee 2.2.0