mirror of
https://github.com/localsend/localsend.git
synced 2026-08-07 07:14:52 +00:00
306 lines
6.6 KiB
Dart
306 lines
6.6 KiB
Dart
import 'dart:convert';
|
|
import 'dart:math';
|
|
|
|
import 'package:crypto/crypto.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
/// The icon alphabet used to visualize fingerprints.
|
|
const iconAlphabet = <IconData>[
|
|
Icons.ac_unit,
|
|
Icons.access_alarm,
|
|
Icons.access_time,
|
|
Icons.accessibility,
|
|
Icons.accessibility_new,
|
|
Icons.account_balance,
|
|
Icons.account_balance_wallet,
|
|
Icons.account_box,
|
|
Icons.account_circle,
|
|
Icons.adb,
|
|
Icons.add,
|
|
Icons.add_a_photo,
|
|
Icons.add_alarm,
|
|
Icons.add_alert,
|
|
Icons.add_box,
|
|
Icons.add_circle,
|
|
Icons.add_circle_outline,
|
|
Icons.add_comment,
|
|
Icons.add_location,
|
|
Icons.add_photo_alternate,
|
|
Icons.add_shopping_cart,
|
|
Icons.alarm,
|
|
Icons.alarm_add,
|
|
Icons.alarm_off,
|
|
Icons.alarm_on,
|
|
Icons.album,
|
|
Icons.all_inbox,
|
|
Icons.all_inclusive,
|
|
Icons.analytics,
|
|
Icons.android,
|
|
Icons.announcement,
|
|
Icons.api,
|
|
Icons.app_blocking,
|
|
Icons.app_registration,
|
|
Icons.app_settings_alt,
|
|
Icons.apple,
|
|
Icons.apps,
|
|
Icons.archive,
|
|
Icons.arrow_back,
|
|
Icons.arrow_back_ios,
|
|
Icons.arrow_downward,
|
|
Icons.arrow_drop_down,
|
|
Icons.arrow_drop_up,
|
|
Icons.arrow_forward,
|
|
Icons.arrow_forward_ios,
|
|
Icons.arrow_left,
|
|
Icons.arrow_right,
|
|
Icons.arrow_upward,
|
|
Icons.article,
|
|
Icons.aspect_ratio,
|
|
Icons.assessment,
|
|
Icons.assignment,
|
|
Icons.assignment_ind,
|
|
Icons.assignment_late,
|
|
Icons.assignment_return,
|
|
Icons.assignment_turned_in,
|
|
Icons.assistant,
|
|
Icons.attach_email,
|
|
Icons.attach_file,
|
|
Icons.attach_money,
|
|
Icons.attachment,
|
|
Icons.attribution,
|
|
Icons.audiotrack,
|
|
Icons.auto_awesome,
|
|
Icons.auto_delete,
|
|
Icons.auto_fix_high,
|
|
Icons.autorenew,
|
|
Icons.backspace,
|
|
Icons.backup,
|
|
Icons.badge,
|
|
Icons.bar_chart,
|
|
Icons.batch_prediction,
|
|
Icons.battery_charging_full,
|
|
Icons.battery_full,
|
|
Icons.battery_std,
|
|
Icons.beach_access,
|
|
Icons.beenhere,
|
|
Icons.block,
|
|
Icons.bluetooth,
|
|
Icons.bluetooth_connected,
|
|
Icons.bluetooth_disabled,
|
|
Icons.bluetooth_searching,
|
|
Icons.book,
|
|
Icons.bookmark,
|
|
Icons.bookmark_border,
|
|
Icons.bookmarks,
|
|
Icons.border_all,
|
|
Icons.border_color,
|
|
Icons.build,
|
|
Icons.business,
|
|
Icons.business_center,
|
|
Icons.calculate,
|
|
Icons.calendar_today,
|
|
Icons.call,
|
|
Icons.call_end,
|
|
Icons.call_made,
|
|
Icons.call_merge,
|
|
Icons.call_missed,
|
|
Icons.call_received,
|
|
Icons.call_split,
|
|
Icons.camera,
|
|
Icons.camera_alt,
|
|
Icons.camera_enhance,
|
|
Icons.camera_front,
|
|
Icons.camera_rear,
|
|
Icons.cancel,
|
|
Icons.card_giftcard,
|
|
Icons.card_membership,
|
|
Icons.card_travel,
|
|
Icons.category,
|
|
Icons.chat,
|
|
Icons.chat_bubble,
|
|
Icons.chat_bubble_outline,
|
|
Icons.check,
|
|
Icons.check_box,
|
|
Icons.check_box_outline_blank,
|
|
Icons.check_circle,
|
|
Icons.check_circle_outline,
|
|
Icons.chevron_left,
|
|
Icons.chevron_right,
|
|
Icons.clear,
|
|
Icons.close,
|
|
Icons.cloud,
|
|
Icons.cloud_circle,
|
|
Icons.cloud_download,
|
|
Icons.cloud_off,
|
|
Icons.cloud_queue,
|
|
Icons.cloud_upload,
|
|
Icons.code,
|
|
Icons.comment,
|
|
Icons.computer,
|
|
Icons.contact_mail,
|
|
Icons.contact_phone,
|
|
Icons.contact_support,
|
|
Icons.contacts,
|
|
Icons.content_copy,
|
|
Icons.content_cut,
|
|
Icons.content_paste,
|
|
Icons.credit_card,
|
|
Icons.crop,
|
|
Icons.dashboard,
|
|
Icons.data_usage,
|
|
Icons.delete,
|
|
Icons.delete_forever,
|
|
Icons.delete_outline,
|
|
Icons.description,
|
|
Icons.desktop_mac,
|
|
Icons.desktop_windows,
|
|
Icons.details,
|
|
Icons.developer_board,
|
|
Icons.developer_mode,
|
|
Icons.device_hub,
|
|
Icons.devices,
|
|
Icons.dialpad,
|
|
Icons.directions,
|
|
Icons.directions_bike,
|
|
Icons.directions_bus,
|
|
Icons.directions_car,
|
|
Icons.directions_run,
|
|
Icons.directions_walk,
|
|
Icons.disc_full,
|
|
Icons.dns,
|
|
Icons.done,
|
|
Icons.done_all,
|
|
Icons.done_outline,
|
|
Icons.drafts,
|
|
Icons.edit,
|
|
Icons.edit_location,
|
|
Icons.email,
|
|
Icons.error,
|
|
Icons.error_outline,
|
|
Icons.event,
|
|
Icons.event_available,
|
|
Icons.event_busy,
|
|
Icons.event_note,
|
|
Icons.event_seat,
|
|
Icons.exit_to_app,
|
|
Icons.expand_less,
|
|
Icons.expand_more,
|
|
Icons.explicit,
|
|
Icons.explore,
|
|
Icons.extension,
|
|
Icons.face,
|
|
Icons.facebook,
|
|
Icons.fast_forward,
|
|
Icons.fast_rewind,
|
|
Icons.favorite,
|
|
Icons.favorite_border,
|
|
Icons.featured_play_list,
|
|
Icons.featured_video,
|
|
Icons.feedback,
|
|
Icons.file_download,
|
|
Icons.file_upload,
|
|
Icons.filter,
|
|
Icons.filter_alt,
|
|
Icons.filter_list,
|
|
Icons.find_in_page,
|
|
Icons.fingerprint,
|
|
Icons.flag,
|
|
Icons.flash_auto,
|
|
Icons.flash_off,
|
|
Icons.flash_on,
|
|
Icons.flight,
|
|
Icons.flight_land,
|
|
Icons.flight_takeoff,
|
|
Icons.folder,
|
|
Icons.folder_open,
|
|
Icons.folder_shared,
|
|
Icons.forum,
|
|
Icons.forward,
|
|
Icons.fullscreen,
|
|
Icons.fullscreen_exit,
|
|
Icons.games,
|
|
Icons.gavel,
|
|
Icons.gesture,
|
|
Icons.get_app,
|
|
Icons.gif,
|
|
Icons.grade,
|
|
Icons.group,
|
|
Icons.group_add,
|
|
Icons.group_work,
|
|
Icons.hd,
|
|
Icons.headset,
|
|
Icons.headset_mic,
|
|
Icons.healing,
|
|
Icons.hearing,
|
|
Icons.help,
|
|
Icons.help_outline,
|
|
Icons.history,
|
|
Icons.home,
|
|
Icons.hotel,
|
|
Icons.hourglass_empty,
|
|
Icons.hourglass_full,
|
|
Icons.http,
|
|
Icons.https,
|
|
Icons.image,
|
|
Icons.image_aspect_ratio,
|
|
Icons.import_contacts,
|
|
Icons.import_export,
|
|
Icons.inbox,
|
|
Icons.info,
|
|
Icons.info_outline,
|
|
Icons.input,
|
|
Icons.key,
|
|
Icons.keyboard,
|
|
Icons.label,
|
|
Icons.landscape,
|
|
Icons.language,
|
|
Icons.laptop,
|
|
Icons.launch,
|
|
Icons.layers,
|
|
Icons.lightbulb,
|
|
Icons.link,
|
|
Icons.list,
|
|
Icons.local_activity,
|
|
Icons.local_airport,
|
|
Icons.local_atm,
|
|
Icons.local_bar,
|
|
Icons.local_cafe,
|
|
Icons.local_dining,
|
|
Icons.local_grocery_store,
|
|
Icons.local_hospital,
|
|
Icons.local_hotel,
|
|
Icons.local_offer,
|
|
Icons.local_phone,
|
|
Icons.local_pizza,
|
|
Icons.local_post_office,
|
|
Icons.local_see,
|
|
Icons.local_shipping,
|
|
Icons.local_taxi,
|
|
Icons.lock,
|
|
Icons.lock_open,
|
|
];
|
|
|
|
/// Hashes the [combined] fingerprints and renders the first 128 bits as 16 icons of [iconAlphabet].
|
|
List<IconData> fingerprintToIcons(String combined) {
|
|
final digest = sha256.convert(utf8.encode(combined));
|
|
final hex = digest.bytes.sublist(0, 16).map((b) => b.toRadixString(16).padLeft(2, '0')).join();
|
|
return convertFingerprintToAlphabet(fingerprint: hex, alphabet: iconAlphabet);
|
|
}
|
|
|
|
/// Converts a hex [fingerprint] to a sequence of items of [alphabet] using base conversion.
|
|
/// The result has a fixed length depending only on the input and alphabet sizes.
|
|
List<T> convertFingerprintToAlphabet<T>({
|
|
required String fingerprint,
|
|
required List<T> alphabet,
|
|
}) {
|
|
final base = BigInt.from(alphabet.length);
|
|
final length = (fingerprint.length * 4 * log(2) / log(alphabet.length)).ceil();
|
|
var value = BigInt.parse(fingerprint, radix: 16);
|
|
final result = List<T>.filled(length, alphabet[0]);
|
|
for (var i = length - 1; i >= 0; i--) {
|
|
result[i] = alphabet[(value % base).toInt()];
|
|
value ~/= base;
|
|
}
|
|
return result;
|
|
}
|