Changes between Version 67 and Version 68 of HashSourceCodes


Ignore:
Timestamp:
Apr 27, 2019, 9:40:54 AM (6 years ago)
Author:
os
Comment:

added Dart

Legend:

Unmodified
Added
Removed
Modified
  • HashSourceCodes

    v67 v68  
    20892089}
    20902090}}}
     2091
     2092== Dart ==
     2093Taken from https://github.com/NBTX/opensubtitles_hash/blob/master/opensubtitles_hash.dart
     2094Check also https://pub.dartlang.org/packages/opensubtitles_hash
     2095   
     2096///
     2097/// Copyright 2019 SamJakob (NBTX, ApolloTV)
     2098///
     2099/// Permission is hereby granted, free of charge, to any person
     2100/// obtaining a copy of this software and associated documentation
     2101/// files (the "Software"), to deal in the Software without
     2102/// restriction, including without limitation the rights to use,
     2103/// copy, modify, merge, publish, distribute, sublicense, and/or
     2104/// sell copies of the Software, and to permit persons to whom the
     2105/// Software is furnished to do so, subject to the following
     2106/// conditions:
     2107///
     2108/// The above copyright notice and this permission notice shall be
     2109/// included in all copies or substantial portions of the Software.
     2110///
     2111/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     2112/// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     2113/// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     2114/// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     2115/// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     2116/// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     2117/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     2118/// OTHER DEALINGS IN THE SOFTWARE.
     2119
     2120library opensubtitles_hash;
     2121
     2122import 'dart:async';
     2123import 'dart:io';
     2124
     2125///
     2126/// Simple Dart implementation of the OpenSubtitles hash algorithm.
     2127///
     2128/// Hash code is based on Media Player Classic. In natural language
     2129/// it calculates: size + 64bit checksum of the first and last 64k
     2130///
     2131/// (even if they overlap because the file is smaller than
     2132/// * 128k).
     2133///
     2134/// Example Usage:
     2135/// --------------
     2136/// String hash = await OpenSubtitlesHasher.computeFileHash(
     2137///   new File('./breakdance.avi')
     2138/// );
     2139///
     2140/// String hash = await OpenSubtitlesHasher.computeURLHash(
     2141///   "http://www.opensubtitles.org/addons/avi/breakdance.avi"
     2142/// )
     2143///
     2144class OpenSubtitlesHasher {
     2145
     2146  // 64 * 1024
     2147  static const HASH_CHUNK_SIZE = 65536;
     2148
     2149  static Future<String> computeURLHash(String url, {
     2150    Map<String, dynamic> headers,
     2151    bool followRedirects = false
     2152  }) async {
     2153
     2154    HttpClient client = new HttpClient();
     2155    HttpClientResponse response;
     2156    response = await client.getUrl(Uri.parse(url))
     2157      .then((HttpClientRequest request){
     2158        // Add headers if they have been provided...
     2159        if(headers != null){
     2160          headers.forEach((String name, dynamic value){
     2161            request.headers.add(name, value.toString());
     2162          });
     2163        }
     2164
     2165        request.followRedirects = followRedirects;
     2166        return request.close();
     2167      });
     2168
     2169    List<List<int>> responseData = await response.toList();
     2170    return await computeHash(
     2171      responseData.expand((i) => i).toList()
     2172    );
     2173
     2174  }
     2175
     2176  static Future<String> computeFileHash(File file) async {
     2177    return await computeHash(await file.readAsBytes());
     2178  }
     2179
     2180  ///
     2181  /// Computes the hash of the byte array parameter.
     2182  ///
     2183  /// This is used by [computeURLHash] and [computeFileHash].
     2184  ///
     2185  static Future<String> computeHash(List<int> subtitleFile) async {
     2186    List<int> data = new List.filled(8, 0, growable: true);
     2187
     2188    /// Perform a shift on the first 8 entries
     2189    /// in [data] relative to the size of the file.
     2190    int temp = subtitleFile.length;
     2191    for(var i = 0; i < 8; i++){
     2192      data[i] = temp & 255;
     2193      temp = temp >> 8;
     2194    }
     2195
     2196    /// Read bytes from 0 to [HASH_CHUNK_SIZE]
     2197    /// and add the value to the corresponding
     2198    /// position in [data].
     2199    for(var i = 0; i < HASH_CHUNK_SIZE; i++){
     2200      data[(i + 8) % 8] += subtitleFile[i];
     2201    }
     2202
     2203    /// Read the last [HASH_CHUNK_SIZE] bytes
     2204    /// and add the value to the corresponding
     2205    /// position in [data].
     2206    int startReference = subtitleFile.length - HASH_CHUNK_SIZE;
     2207    for(var i = startReference; i < subtitleFile.length; i++){
     2208      int fileOffset = i - startReference;
     2209      data[(fileOffset + 8) % 8] += subtitleFile[i];
     2210    }
     2211
     2212    return _binl2hex(data);
     2213  }
     2214
     2215  static _binl2hex(a) {
     2216    var b = 255,
     2217        c = 7,
     2218        d = '0123456789abcdef',
     2219        e = '';
     2220
     2221    a[1] += a[0] >> 8;
     2222    a[0] = a[0] & b;
     2223    a[2] += a[1] >> 8;
     2224    a[1] = a[1] & b;
     2225    a[3] += a[2] >> 8;
     2226    a[2] = a[2] & b;
     2227    a[4] += a[3] >> 8;
     2228    a[3] = a[3] & b;
     2229    a[5] += a[4] >> 8;
     2230    a[4] = a[4] & b;
     2231    a[6] += a[5] >> 8;
     2232    a[5] = a[5] & b;
     2233    a[7] += a[6] >> 8;
     2234    a[6] = a[6] & b;
     2235    a[7] = a[7] & b;
     2236    for (c; c > -1; c--) {
     2237        e += d[(a[c] >> 4 & 15)] + d[(a[c] & 15)];
     2238    }
     2239    return e;
     2240  }
     2241
     2242}