#!/usr/bin/env perl use 5.014; use strict; use warnings; use autodie; use charnames qw(:full); use Path::Tiny; use Data::Dumper; use utf8; use Unicode::Normalize qw(NFD NFC); use Encode; use open qw(:std :utf8); my $ch = { c => "\N{U+0010C}", # LATIN CAPITAL LETTER C WITH CARON a => "\N{U+000E1}", # LATIN SMALL LETTER A WITH ACUTE r => "\N{U+00158}", # LATIN CAPITAL LETTER R WITH CARON y => "\N{U+000FD}", # LATIN SMALL LETTER Y WITH ACUTE }; my $str = join '', @$ch{qw(c a r y)}; my $name = { nfc => NFC($str), #not needed - the result is the same - only for consistency nfd => NFD($str), }; my $tmp = Path::Tiny->tempdir(DIR => ".", CLEANUP => 0); #dump info make_txt_files($tmp); make_img_files($tmp); say "Dump of the $tmp entries"; printout($_->basename) for $tmp->children; sub printout { my($bytes) = @_; state $n++; my $uname = decode_utf8($bytes); say "---[entry #$n]--[$uname]---"; say "RawHex :\t", map { s/(..)/$1 /gr } unpack "H*", $bytes; my @chars = split //, $uname; say "Unichar:\t", map { sprintf "\\N{U+%04x}", ord($_) } @chars; printf "U+%05X\t%s\n", ord($_), charnames::viacode(ord($_)) for @chars; } sub make_txt_files { my $dir = shift; my $nfcfile = $dir->child( $name->{nfc} . ".txt" ); my $nfdfile = $dir->child( $name->{nfd} . ".txt" ); $nfcfile->spew_utf8("this file has NFC filename [$name->{nfc}]\n"); return if $nfdfile->exists; $nfdfile->spew_utf8("this file has NFD filename [$name->{nfd}]\n"); } sub make_img_files { my $dir = shift; my $nfcfile = $dir->child( $name->{nfc} . ".png" ); my $nfdfile = $dir->child( $name->{nfd} . ".png" ); my $image = pack 'H*', map s/\s+//gr, do { local $/; scalar }; $nfcfile->spew_raw($image); return if $nfdfile->exists; $nfdfile->spew_raw($image); } __DATA__ 89504e470d0a1a0a0000000d49484452000000cc0000001f080400000001 81eaf8000000206348524d00007a26000080840000fa00000080e8000075 300000ea6000003a98000017709cba513c00000002624b474400ff878fcc bf000000097048597300000b1300000b1301009a9c18000005c049444154 68deedd87d9057551dc7f1d7b280100fc2020b8a3ca9ac954836e4d44c8e 40018e23b698d22030254a6565a412516266cd34ad0f9099a699292e94c3 90b13080944441412bcb0046e900cdf21cecc2b23c2cb10bbb7bfb83bb3f 7f0f777fb030b6cc78dfbfd99973bff77bbf9f73bedf73cf3d6789898989 89898989898989898989f90092a3676b77e1ff4fb120edf79842812e2d8e b4cf77de971e7ecd7f047ab576a2b232d8d81667a19dc00f524d6d93da4f fa0df8a5fd1e03ff36a4b5c79944ae47cdf7b4c3addd91acdc66a6de6099 6de71f26b9305b6c01c755fa4368bb980a93a78f95f6b57637ce99af5cc8 c36dcec1e73aabfdd7765f0faf3f6e85c34e2af319b0ce7045ca559a9bb6 ec0df6573f4e5c7555ea8b61bba3bf2b4407b3bdabda9f8c0cefacf3b9b0 75afc549b1eef6473c6309b8cb5ac76cf23d39e029335d6fb11753f4a77a 4b8d6dbe1d7a65aa655a569a68b61d0e58a86f68bbda12876cf67d3968ab cc274c556a1ceeb1c549d57ea7075ef7803c651ec4f270b4e91a3759abaf c50e27721a847f67614b52420a05762a32d90a8161e8e1a052f7b9cb7a47 e4a2ce264b4df6943a45685a5d07d9e30d1d9222afb0266c8d735a2f39d6 38ee6193bca13e5c9bebdc13fa3c6247d2b3377a5ca0d8b7304da0d8044f 38edd7a0c46bcaad4d99a533045e30d90b1acc22422d4abfca7e65be6c9a 1df6e886418e5862a2471c3707ed058a1c53e27a770abc64826f3aea65dc 6f851a8fba3991854c8d42a76d4cc92935a6b5bc300f812e4e9a81db9d74 0d182e50803aeb42ef45ca1285e96787652e49893c4183cb40b1a5b84360 34c8f167efc8c952187a09dc8caeaa136fc637341a8a128d1e4cf1eeaada ecb0fd5b7b22d5a2f4abecd619f4576b16e627a6d3edeaf5d65ee0888f82 f9e18879d666f0908ad072a630991a9939659749a9453897a56c11386ebb 9e58a4a3adda19ea5eb40be7eb1936ea11b6fa5aa5bbf1ea52229538e60e b433d63c8cb6dd9b20f0bc8f24968eecdca09be7c2f6afd41b05f67b26c3 ebe5b0fd254322d5a2f55f5303765b6e0cc6586f986186d9a7d16d609e77 c06437e052a38cd23eb2b7d11aa939a54a55cb0b7328edfaabd63b61a52b 323c82702d679a03ba26be4a4dd45a603c46c8b518039527ee9563e03915 66008977e994bd068077356478ed0adba71d8d548bd6df95b0edd45f67bd 4cb7c1061bbca59dcbc13f438f1e9e56eeb05fa86da6b7d11ae9393d743e 85492fcbcfbdaaaffcf0758c66b9915ef24383d2ec73dde8329fb7502d0e 261d177b6674b75333b10f85de4dcf9d79aa3acdeb2889ad4817d7c88d50 8bd6ef9eb07557ed841366e89df8cd49515be056537552605933bdcd3ec6 26f63978a185b945a9e71cc45559bc56ab37538de7d3eca5b6bb53a17960 93ebc2f9ce584795e3443827f96433b1dfd69838c40dd7c5a648af7f11ae edfcc41a8d116a51fa12b1738df6b6c0264355aa54295771ca72dbc1483f b34a6d966c446ba433c5ceb3a73efde3df34effee171bca2c2b5ba1863a7 c028519feba633ef24818969d1bfeb805de192d75985f53e26cffd4e7918 fcc5769f926f96a3cd7cfc79d511e35dea26e536ca41898519e358aac267 f532458da248b528fd2a0de6e867a057c28dc558f5a6eb6d8812ab9cd995 7d01e4386e913c7d4c576faf4eb84fad11ae486421532333a7036cf6a30b 2dcc605b05025b7dda5e81b6590ac39b2ae5a544efab21e96c53e06f1a04 8e9815bebdc3ec16a857e281660bd3d1b34e089cb2583ecd1426cf02a704 eabd187e9833d5322d559eb05620b0c7ad61a4bb5508d458e4da94c230c5 31817aaf1ba7d1ef31c8360d7e9a9485748dcc9c1608cc3d7b61ce468efe e1bad9f13cfea558a0d187532c1fd23f2d7ebf70c39a8d360636b30f4aa6 bd2bd3b6ece96ae9962ad3d027dcd6bfc7e52927b2f7e8e0aaf04e7e9a52 76d58b8a3672ccb5bab5bb9195aa7339eabdffb4bdf0102d60aa27b535a2 b5071d934ebe5b3296888b8dab756bed2ec4c4c4c4c4c4c47c00f91fa69d 28ba1ad7970f0000000049454e44ae426082