Files
localsend/app/lib/util/fingerprint_alphabet.dart
T
2026-08-04 17:20:31 +02:00

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;
}