✂ Rextended Fragments of Snippets

Over the years I have published dozens of scripts,
most need to be updated and are hard to find with standard search.
And they also need to be checked if they are still valid for the new stable v7 version.

I’m slowly re-reading all of my 10000 posts
and I’ll add here all the useful Snippets I found,
with a description and the link to the topic where they are present.

In the future, when I’m done, I’ll index everything for better search.

2 Likes

wireless on off with mode button
http://forum.mikrotik.com/t/wi-fi-on-off-switch/103825/17

create directory and subdirectory
http://forum.mikrotik.com/t/mkdir-function-for-easy-folder-creation/132775/14

mac ping results saved on variable
http://forum.mikrotik.com/t/how-to-get-the-avg-rtt-value-of-command-ping/63496/5

Put snmp-get value on variable
http://forum.mikrotik.com/t/routeros-snmp-get/121369/13

Convert character to uppercase or lowercase
http://forum.mikrotik.com/t/i-did-it-script-to-compute-unix-time/68576/18

UNIX time Epoch, day of the week, ISO:8601 date
http://forum.mikrotik.com/t/i-did-it-script-to-compute-unix-time/68576/1

Import IP or IP prefix from file
http://forum.mikrotik.com/t/importing-ip-list-from-file/143071/1

How to download only one piece of file at a time with /tool fetch and put it inside a variable
http://forum.mikrotik.com/t/how-to-download-only-one-piece-of-file-at-a-time-with-tool-fetch-and-put-it-inside-a-variable/151020/1

Decode USSD hexstr2chrstr hexadecimal string to char string
http://forum.mikrotik.com/t/decode-ussd-on-wap-lte-kit/115644/4

hex2chr hexadecimal to char
http://forum.mikrotik.com/t/how-to-convert-a-hex-value-to-a-char/97913/9

definitive ip or ip-prefix posix regex
http://forum.mikrotik.com/t/address-lists-downloader-dshield-spamhaus-drop-edrop-etc/133640/88

auto add (starlink) classless route
http://forum.mikrotik.com/t/classless-routes-not-being-added-by-dhcp-client/149116/21

int2hex num2hex integer number to hexadecimal convert function
http://forum.mikrotik.com/t/how-to-covert-int-to-hex-type-value-and-save-it-in-a-string/52654/6

check host status
http://forum.mikrotik.com/t/incomprehensible-behavior-of-netwatch-and-a-script-that-imitates-it/150559/2

dual wan A-B-C failover
http://forum.mikrotik.com/t/wan-load-balancing-between-2-isps-one-with-cgnat-and-another-in-bridge-mode-real-ipv4-address/150195/2

dual dhcp wan failover
http://forum.mikrotik.com/t/dual-wan-failover-script-ping-command/150516/8

How to really block invalid ICMP, TCP, UDP packets and others (ver. 2021)
https://forum.mikrotik.com/viewtopic.php?f=9&t=83387&p=867386

comma separated value of interface list
http://forum.mikrotik.com/t/crs-vlan-add-untagged-interfaces-via-script/150066/8

num2month mon2MON mon2num number month
http://forum.mikrotik.com/t/changing-from-number-to-date/150050/3

short address list ip address aggregator (to do)
http://forum.mikrotik.com/t/how-to-opitimize-list-of-ip4-addresses/129916/8

send whatsapp notification
http://forum.mikrotik.com/t/send-mikrotik-notification-via-whatsapp/110950/19

asynchronous script execution
http://forum.mikrotik.com/t/suppress-output-from-ping-in-script/79536/6

enable x64 mode on RouterOS x86 installed on x64 (virtual or not) machine
http://forum.mikrotik.com/t/x86-64-ros-64bit-mikrotik/104992/83

random number generator (without OTP frills)
http://forum.mikrotik.com/t/random-number-between-0-and-99-or-string-between-00-and-99/149267/1

default firewall rules
http://forum.mikrotik.com/t/buying-rb1100ahx4-dude-edition-questions-about-firewall/148996/4

convert string to ip-prefix
http://forum.mikrotik.com/t/help-with-error-in-script-to-import-the-ipv4-full-bogons-list-from-www-team-cymru-org/113429/4

dynamic variables
http://forum.mikrotik.com/t/concatenate-values-to-create-variable-name/151793/2

manage fetch errors
http://forum.mikrotik.com/t/fetch-capable-of-following-redirects/151723/7

sort array, sort file by date, date2ymd
http://forum.mikrotik.com/t/sorted-array-of-files/151870/1

ip2array ip split octet
http://forum.mikrotik.com/t/return-ip-octet-function/77321/15

DHCPv6 option 39 fqdn2encdns FQDN to DNS encoding DNS encoder

http://forum.mikrotik.com/t/option39-dhcpv6-client/151933/8

Save and Restore global variables on reboot

http://forum.mikrotik.com/t/persistent-environment-variables/145326/6

Save RouterBOARD full backup of everything [configuration, certificates, host key, router users (no passwords), licence, user-manager, dude, other files]
http://forum.mikrotik.com/t/router-crashes-are-wiping-the-config/149189/7

Online function to obtain the start date and time of the RouterBOARD.
It takes into account the time zone set in the RouterBOARD.
http://forum.mikrotik.com/t/convert-uptime-to-date-and-time/157724/1

Convert float to Celsius for TG-BT5-OUT
http://forum.mikrotik.com/t/float-datatype/158109/5

Convert the date string (May|may)/23/2022 to number 20220523
(the “date” type on RouterOS do not exist)
http://forum.mikrotik.com/t/sms-timestamp-system-date-and-case-sensitive/158216/5

From 2014: I forgot that on print and on find is possible to do some operations insde search string…
like (just an example)

/ip address print where (network + 1) = 192.168.88.1

http://forum.mikrotik.com/t/script-find-where-routing-mark-stops-work-routeros6-7/74610/4

SMS GSM alphabet

http://forum.mikrotik.com/t/sms-charset-problem/74623/2

TAG # lastcheck (25 Mar 2014, 13:34)

http://forum.mikrotik.com/t/v6-11-released/75450/120


TAG: ###RCHCK###

Check if the URL is valid and read server response and redirects:
http://forum.mikrotik.com/t/address-lists-downloader-dshield-spamhaus-drop-edrop-etc/133640/157

Create a log file and dynamically split the file every 4095 Bytes or less
http://forum.mikrotik.com/t/script-fails-to-create-file/160011/7

Obtain some info from one IP, convert subnet mask to prefix, convert prefix to subnet mask, convert IP to num, convert num to IP, convert IP to HEX, convert HEX to IP etc.

If the IP have (do not have) subnet mask different from /32 (255.255.255.255)
other useful info can be obtained from this information.
(MikroTik actually do not support directly /31 addresses)

For example if you have this 10.31.42.56/16

{
:local source    10.31.42.56/16

:local ip        [:toip [:pick $source 0 [:find $source "/"]]]
:local prefix    [:tonum [:pick $source ([:find $source "/"] + 1) [:len $source]]]
:local submask   (255.255.255.255<<(32 - $prefix))
:local addrspace (~$submask)
:local totip     ([:tonum $addrspace] + 1)
:local network   ($ip & $submask)
:local broadcast ($ip | $addrspace)
:local first     (($network     + 1) - ($prefix / 31))
:local last      (($broadcast   - 1) + ($prefix / 31))
:local usable    (($last - $network) + ($prefix / 31))
:put "       Source: $source"
:put "           IP: $ip"
:put "Subnet Prefix: $prefix"
:put "  Subnet Mask: $submask"
:put "Address Space: $addrspace"
:put "    Total IPs: $totip"
:put "  Network* IP: $network"
:put "Broadcast* IP: $broadcast"
:put "    First* IP: $first"
:put "     Last* IP: $last"
:put "  Usable* IPs: $usable"
}
  • = Network / Broadcast / First IP and Last IP are valid only when the IP are distribuited on local LAN,
    instead for routing only, all IP can be used.
    .0 and .255 are perfectly valid IP if are not the network ip or the broadcast address,
    but for compatibility with some end devices that have problems with .0 and .255 outside a /24, is better remove all .0 and all .255 from the IP pools assigned from DHCP Server.

For example if you have this IP 10.31.42.56 and subnet 255.255.0.0

{
:local sourceip    10.31.42.56
:local sourcesub   255.255.0.0

:local ip        [:toip $sourceip]
:local submask   [:toip $sourcesub]
:local addrspace (~$submask)
:local tempsub   [:tonum $addrspace]
:local prefix    32
:while ($tempsub > 0) do={:set tempsub ($tempsub / 2); :set prefix ($prefix - 1)}
:local totip     ([:tonum $addrspace] + 1)
:local network   ($ip & $submask)
:local broadcast ($ip | $addrspace)
:local first     (($network     + 1) - ($prefix / 31))
:local last      (($broadcast   - 1) + ($prefix / 31))
:local usable    (($last - $network) + ($prefix / 31))
:put "    Source IP: $ip"
:put "  Source Mask: $submask"
:put "Subnet Prefix: $prefix"
:put "Address Space: $addrspace"
:put "    Total IPs: $totip"
:put "  Network* IP: $network"
:put "Broadcast* IP: $broadcast"
:put "    First* IP: $first"
:put "     Last* IP: $last"
:put "  Usable* IPs: $usable"
}

Convert IP to decimal number: (127.0.0.1 = 2130706433)

:put [:tonum 127.0.0.1]

Convert decimal number to IP: (2130706433 = 127.0.0.1)

:put (0.0.0.0 + 2130706433)

Convert IP to hexadecimal number
Using this:
http://forum.mikrotik.com/t/how-to-covert-int-to-hex-type-value-and-save-it-in-a-string/52654/6
The IP can be converted first to decimal, then to hexadecimal.

:put [$num2hex [:tonum 127.0.0.1]]

Convert hexadecimal number to IP

:put (0.0.0.0 + 0x7F000001)

Script for convert codepage or replace characters inside a string
http://forum.mikrotik.com/t/convert-identity-name-to-uppercase/161897/6

decimal 2 binary (only 1 BYTE)

:global dec2bin do={
    :local number [:tonum $1]
    :local b8 0 ; :if ($number & 128) do={:set b8 1}
    :local b7 0 ; :if ($number &  64) do={:set b7 1}
    :local b6 0 ; :if ($number &  32) do={:set b6 1}
    :local b5 0 ; :if ($number &  16) do={:set b5 1}
    :local b4 0 ; :if ($number &   8) do={:set b4 1}
    :local b3 0 ; :if ($number &   4) do={:set b3 1}
    :local b2 0 ; :if ($number &   2) do={:set b2 1}
    :local b1 0 ; :if ($number &   1) do={:set b1 1}
    :return "$b8$b7$b6$b5$b4$b3$b2$b1"
}

see here for version from 0 to 9.223.372.036.854.775.807 auto BYTE / WORD / DWORD / QWORD version:
http://forum.mikrotik.com/t/rextended-fragments-of-snippets/151033/1



hexadecimal 2 binary (only 1 byte) expected as 0x00 … 0xFF or 00… FF value:

:global hex2bin do={
    :local conv $1
    :if (!($conv~"(^0x|^)[0-9a-fA-F]{2}\$")) do={:return "00000000"}
    :if ([:typeof [:find $conv "0x" -1]] = "nil") do={:set conv "0x$conv"}
    :local number [:tonum $conv]
    :local b8 0 ; :if ($number & 128) do={:set b8 1}
    :local b7 0 ; :if ($number &  64) do={:set b7 1}
    :local b6 0 ; :if ($number &  32) do={:set b6 1}
    :local b5 0 ; :if ($number &  16) do={:set b5 1}
    :local b4 0 ; :if ($number &   8) do={:set b4 1}
    :local b3 0 ; :if ($number &   4) do={:set b3 1}
    :local b2 0 ; :if ($number &   2) do={:set b2 1}
    :local b1 0 ; :if ($number &   1) do={:set b1 1}
    :return "$b8$b7$b6$b5$b4$b3$b2$b1"
}

see here for version from 0 to 9.223.372.036.854.775.807 auto BYTE / WORD / DWORD / QWORD version:
http://forum.mikrotik.com/t/rextended-fragments-of-snippets/151033/1

binary to decimal (only 8 bit / 1 byte) from 00000000 to 11111111

:global bin2dec do={
    :local bin $1
    :local dec  0
    :local mol  1
    :if (!($bin~"^[0-1]{8}\$")) do={:return 0}
    :for pos from=1 to=8 do={
        :local temp [:tonum [:pick $bin (8 - $pos) (8 - $pos + 1)]]
        :set dec ($dec + ($temp * $mol))
        :set mol ($mol * 2)
    }
    :return $dec
}

binary to hexadecimal (only 8 bit / 1 byte) from 00000000 to 11111111
the output is on 0x00 … 0xFF format, for remove the 0x simplu remove 0x on last “:return”

:global bin2hex do={
    :local bin $1
    :local dec  0
    :local mol  1
    :if (!($bin~"^[0-1]{8}\$")) do={:return "0x00"}
    :for pos from=1 to=8 do={
        :local temp [:tonum [:pick $bin (8 - $pos) (8 - $pos + 1)]]
        :set dec ($dec + ($temp * $mol))
        :set mol ($mol * 2)
    }
    :local hexadec   "0"
    :local remainder 0
    :local hexChars  "0123456789ABCDEF"
    :if ($dec > 0) do={:set hexadec ""}
    :while ( $dec > 0 ) do={
          :set remainder ($dec % 16)
          :set dec       (($dec-$remainder) / 16)
          :set hexadec   ([:pick $hexChars $remainder].$hexadec)
    } 
    :if ([:len $hexadec] = 1) do={:set hexadec "0$hexadec"}
    :return "0x$hexadec"
}

this is the version of binary to decimal that support binary signed QWORD (64 bit) and is the max supported from RouterOS

:global binQW2dec do={
    :local bin $1
    :local dec  0
    :local mol  1
    :local lgt [:len $bin]
    :if (!($bin~"^[0-1]{$lgt}\$")) do={:return 0}
    :for pos from=1 to=$lgt do={
        :local temp [:tonum [:pick $bin ($lgt - $pos) ($lgt - $pos + 1)]]
        :set dec ($dec + ($temp * $mol))
        :set mol ($mol * 2)
    }
    :return $dec
}

this is the version of binary to hexadecimal that support binary signed QWORD (64 bit) and is the max supported from RouterOS

:global binQW2hex do={
    :local bin $1
    :local dec  0
    :local mol  1
    :local lgt [:len $bin]
    :if (!($bin~"^[0-1]{$lgt}\$")) do={:return "0x00"}
    :for pos from=1 to=$lgt do={
        :local temp [:tonum [:pick $bin ($lgt - $pos) ($lgt - $pos + 1)]]
        :set dec ($dec + ($temp * $mol))
        :set mol ($mol * 2)
    }
    :local firstchar ""
    :if ($dec < 0) do={
        :local chk (($dec & 0x7000000000000000) >> 60)
        :set firstchar [:pick "89ABCDEF" $chk ($chk + 1)]
        :set dec ($dec & 0x0FFFFFFFFFFFFFFF)
    }
    :local hexadec   "0"
    :local remainder 0
    :local hexChars  "0123456789ABCDEF"
    :if ($dec > 0) do={:set hexadec ""}
    :while ( $dec > 0 ) do={
          :set remainder ($dec % 16)
          :set dec       (($dec-$remainder) / 16)
          :set hexadec   ([:pick $hexChars $remainder].$hexadec)
    } 
    :if ($firstchar != "") do={
        :set hexadec "00000000000000$hexadec"
        :set hexadec "$firstchar$[:pick $hexadec ([:len $hexadec] - 15) [:len $hexadec]]"
    }
    :return "0x$hexadec"
}

for convert decimal to hexadecimal (not only one byte) can be used:
http://forum.mikrotik.com/t/how-to-covert-int-to-hex-type-value-and-save-it-in-a-string/52654/6

for convert hexadecimal to decimal, on RouterOS already exist this two methods (0x must be present):

:put 0xFF85

:put [:tonum "0xFF85"]

but this can be used (not only one byte):

:global hex2dec do={
    :local conv $1
    :if (!($conv~"^[0-9a-fA-F]+\$")) do={:return 0}
    :if ([:typeof [:find $conv "0x" -1]] = "nil") do={:set conv "0x$conv"}
    :return [:tonum $conv]
}

WARNING: RouterOS have a bug that do not recognize negative hex values, on future I mod the previous script to support QWORD hex conversion

Convert string from ASCII 8-bit CP1252 to UNICODE entry points

:global ASCIItoCP1252toUNICODE do={
    :local ascii "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\
                  \10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\
                  \20\21\22\23\24\25\26\27\28\29\2A\2B\2C\2D\2E\2F\
                  \30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\
                  \40\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\
                  \50\51\52\53\54\55\56\57\58\59\5A\5B\5C\5D\5E\5F\
                  \60\61\62\63\64\65\66\67\68\69\6A\6B\6C\6D\6E\6F\
                  \70\71\72\73\74\75\76\77\78\79\7A\7B\7C\7D\7E\7F\
                  \80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\
                  \90\91\92\93\94\95\96\97\98\99\9A\9B\9C\9D\9E\9F\
                  \A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\
                  \B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\
                  \C0\C1\C2\C3\C4\C5\C6\C7\C8\C9\CA\CB\CC\CD\CE\CF\
                  \D0\D1\D2\D3\D4\D5\D6\D7\D8\D9\DA\DB\DC\DD\DE\DF\
                  \E0\E1\E2\E3\E4\E5\E6\E7\E8\E9\EA\EB\EC\ED\EE\EF\
                  \F0\F1\F2\F3\F4\F5\F6\F7\F8\F9\FA\FB\FC\FD\FE\FF"
    :local CP1252toUNICODE {"0000";"0001";"0002";"0003";"0004";"0005";"0006";"0007";"0008";"0009";"000A";"000B";"000C";"000D";"000E";"000F";
                         "0010";"0011";"0012";"0013";"0014";"0015";"0016";"0017";"0018";"0019";"001A";"001B";"001C";"001D";"001E";"001F";
                         "0020";"0021";"0022";"0023";"0024";"0025";"0026";"0027";"0028";"0029";"002A";"002B";"002C";"002D";"002E";"002F";
                         "0030";"0031";"0032";"0033";"0034";"0035";"0036";"0037";"0038";"0039";"003A";"003B";"003C";"003D";"003E";"003F";
                         "0040";"0041";"0042";"0043";"0044";"0045";"0046";"0047";"0048";"0049";"004A";"004B";"004C";"004D";"004E";"004F";
                         "0050";"0051";"0052";"0053";"0054";"0055";"0056";"0057";"0058";"0059";"005A";"005B";"005C";"005D";"005E";"005F";
                         "0060";"0061";"0062";"0063";"0064";"0065";"0066";"0067";"0068";"0069";"006A";"006B";"006C";"006D";"006E";"006F";
                         "0070";"0071";"0072";"0073";"0074";"0075";"0076";"0077";"0078";"0079";"007A";"007B";"007C";"007D";"007E";"007F";
                         "20AC";"FFFD";"201A";"0192";"201E";"2026";"2020";"2021";"02C6";"2030";"0160";"2039";"0152";"FFFD";"017D";"FFFD";
                         "FFFD";"2018";"2019";"201C";"201D";"2022";"2013";"2014";"02DC";"2122";"0161";"203A";"0153";"FFFD";"017E";"0178";
                         "00A0";"00A1";"00A2";"00A3";"00A4";"00A5";"00A6";"00A7";"00A8";"00A9";"00AA";"00AB";"00AC";"00AD";"00AE";"00AF";
                         "00B0";"00B1";"00B2";"00B3";"00B4";"00B5";"00B6";"00B7";"00B8";"00B9";"00BA";"00BB";"00BC";"00BD";"00BE";"00BF";
                         "00C0";"00C1";"00C2";"00C3";"00C4";"00C5";"00C6";"00C7";"00C8";"00C9";"00CA";"00CB";"00CC";"00CD";"00CE";"00CF";
                         "00D0";"00D1";"00D2";"00D3";"00D4";"00D5";"00D6";"00D7";"00D8";"00D9";"00DA";"00DB";"00DC";"00DD";"00DE";"00DF";
                         "00E0";"00E1";"00E2";"00E3";"00E4";"00E5";"00E6";"00E7";"00E8";"00E9";"00EA";"00EB";"00EC";"00ED";"00EE";"00EF";
                         "00F0";"00F1";"00F2";"00F3";"00F4";"00F5";"00F6";"00F7";"00F8";"00F9";"00FA";"00FB";"00FC";"00FD";"00FE";"00FF"
                        }
    :local string $1
    :if (([:typeof $string] != "str") or ($string = "")) do={ :return "" }
    :local lenstr [:len $string]
    :local constr ""
    :for pos from=0 to=($lenstr - 1) do={
        :local unicode "0x$($CP1252toUNICODE->[:find $ascii [:pick $string $pos ($pos + 1)] -1])"
        :set constr "$constr$unicode"
    }
    :return $constr
}

:put [$ASCIItoCP1252toUNICODE "test"]

0x81, 0x8F, 0x8D, 0x90, 0x9D (not assigned on CP1252) => 0xFFFD REPLACEMENT CHARACTER �




Convert string from ASCII 8-bit CP1252 to UTF-8 string with each byte escaped with %

:global ASCIItoCP1252toUTF8 do={
    :local ascii "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\
                  \10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F\
                  \20\21\22\23\24\25\26\27\28\29\2A\2B\2C\2D\2E\2F\
                  \30\31\32\33\34\35\36\37\38\39\3A\3B\3C\3D\3E\3F\
                  \40\41\42\43\44\45\46\47\48\49\4A\4B\4C\4D\4E\4F\
                  \50\51\52\53\54\55\56\57\58\59\5A\5B\5C\5D\5E\5F\
                  \60\61\62\63\64\65\66\67\68\69\6A\6B\6C\6D\6E\6F\
                  \70\71\72\73\74\75\76\77\78\79\7A\7B\7C\7D\7E\7F\
                  \80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\
                  \90\91\92\93\94\95\96\97\98\99\9A\9B\9C\9D\9E\9F\
                  \A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\
                  \B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\
                  \C0\C1\C2\C3\C4\C5\C6\C7\C8\C9\CA\CB\CC\CD\CE\CF\
                  \D0\D1\D2\D3\D4\D5\D6\D7\D8\D9\DA\DB\DC\DD\DE\DF\
                  \E0\E1\E2\E3\E4\E5\E6\E7\E8\E9\EA\EB\EC\ED\EE\EF\
                  \F0\F1\F2\F3\F4\F5\F6\F7\F8\F9\FA\FB\FC\FD\FE\FF"
    :local CP1252toUTF8 {"00";"01";"02";"03";"04";"05";"06";"07";"08";"09";"0A";"0B";"0C";"0D";"0E";"0F";
                         "10";"11";"12";"13";"14";"15";"16";"17";"18";"19";"1A";"1B";"1C";"1D";"1E";"1F";
                         "20";"21";"22";"23";"24";"25";"26";"27";"28";"29";"2A";"2B";"2C";"2D";"2E";"2F";
                         "30";"31";"32";"33";"34";"35";"36";"37";"38";"39";"3A";"3B";"3C";"3D";"3E";"3F";
                         "40";"41";"42";"43";"44";"45";"46";"47";"48";"49";"4A";"4B";"4C";"4D";"4E";"4F";
                         "50";"51";"52";"53";"54";"55";"56";"57";"58";"59";"5A";"5B";"5C";"5D";"5E";"5F";
                         "60";"61";"62";"63";"64";"65";"66";"67";"68";"69";"6A";"6B";"6C";"6D";"6E";"6F";
                         "70";"71";"72";"73";"74";"75";"76";"77";"78";"79";"7A";"7B";"7C";"7D";"7E";"7F";
      "E282AC";"EFBFBD";"E2809A";"C692";"E2809E";"E280A6";"E280A0";"E280A1";"CB86";"E280B0";"C5A0";"E280B9";"C592";"EFBFBD";"C5BD";"EFBFBD";
      "EFBFBD";"E28098";"E28099";"E2809C";"E2809D";"E280A2";"E28093";"E28094";"CB9C";"E284A2";"C5A1";"E280BA";"C593";"EFBFBD";"C5BE";"C5B8";
                         "C2A0";"C2A1";"C2A2";"C2A3";"C2A4";"C2A5";"C2A6";"C2A7";"C2A8";"C2A9";"C2AA";"C2AB";"C2AC";"C2AD";"C2AE";"C2AF";
                         "C2B0";"C2B1";"C2B2";"C2B3";"C2B4";"C2B5";"C2B6";"C2B7";"C2B8";"C2B9";"C2BA";"C2BB";"C2BC";"C2BD";"C2BE";"C2BF";
                         "C380";"C381";"C382";"C383";"C384";"C385";"C386";"C387";"C388";"C389";"C38A";"C38B";"C38C";"C38D";"C38E";"C38F";
                         "C390";"C391";"C392";"C393";"C394";"C395";"C396";"C397";"C398";"C399";"C39A";"C39B";"C39C";"C39D";"C39E";"C39F";
                         "C3A0";"C3A1";"C3A2";"C3A3";"C3A4";"C3A5";"C3A6";"C3A7";"C3A8";"C3A9";"C3AA";"C3AB";"C3AC";"C3AD";"C3AE";"C3AF";
                         "C3B0";"C3B1";"C3B2";"C3B3";"C3B4";"C3B5";"C3B6";"C3B7";"C3B8";"C3B9";"C3BA";"C3BB";"C3BC";"C3BD";"C3BE";"C3BF"
                        }
    :local string $1
    :if (([:typeof $string] != "str") or ($string = "")) do={ :return "" }
    :local lenstr [:len $string]
    :local constr ""
    :for pos from=0 to=($lenstr - 1) do={
        :local utf ($CP1252toUTF8->[:find $ascii [:pick $string $pos ($pos + 1)] -1])
        :local sym ""
        :if ([:len $utf] = 2) do={:set sym "%$[:pick $utf 0 2]" }
        :if ([:len $utf] = 4) do={:set sym "%$[:pick $utf 0 2]%$[:pick $utf 2 4]" }
        :if ([:len $utf] = 6) do={:set sym "%$[:pick $utf 0 2]%$[:pick $utf 2 4]%$[:pick $utf 4 6]" }
        :set constr "$constr$sym"
    }
    :return $constr
}

:put [$ASCIItoCP1252toUTF8 "test"]

0x81, 0x8F, 0x8D, 0x90, 0x9D (not assigned on CP1252) => %EF%BF%BD REPLACEMENT CHARACTER �

The BOM, Byte Order Mark for UTF-8 is “%EF%BB%BF”