mIRC Home    About    Download    Register    News    Help

Active Threads | Unanswered Past 24 hours | Past 48 hours | Past Week | Past Month | Past Year
Feature Suggestions Jump to new posts
New switches for $input: maroon 13 hours ago

1. Extend 'b' to 'b[N]' which allows optionally specifying the number of seconds to disable the buttons, with the default for 'b' remaining 1 second. A reasonable max seconds could be enforced if that would be appropriate. b0 would clear the keyboard input buffer as 'b' currently does, without any delay.

2. New switch 'F[N]' or similar which allows you to set Focus for which button activates when the spacebar or <enter> is pressed. 'F' or 'F0' would cause none of the buttons to have the focus, 'F1' and 'F2' would be 1st and 2nd buttons respectively. Any N greater than the number of visible buttons would be same as 'F0'. If is easier to have the N be required with 'F', that's fine.

These would allow making sure the user has more than 1 second to read an important prompt message before responding.
Also allows changing the default action away from the 1st button
Also allows requires something more than spacebar or <enter> to trigger a reply
Also allows ignoring the existing contents of the keyboard input buffer without a delay.

sendkeys shows that in the absence of the 'b' switch, $input currently behaves like clicking on YES when there's a spacebar or <enter> already in the keyboard buffer.

Code
//sendkeys $({,0) $(},0) | echo -a noop $input(test1,y) | echo -a noop $input(test2,y)
//sendkeys ~             | echo -a noop $input(test1,y) | echo -a noop $input(test2,y)



'b5' would allow 5 seconds for reading the prompt before accepting keyboard or mouse input. 'F0' would move the focus away from any of the buttons, requiring a <tab> before the spacebar or <enter> would activate a button.
0 22 Read More
Feature Suggestions Jump to new posts
Re: Updated $encode Blowfish improvements wishlist maroon 13 hours ago
Re: (#3) I see v7.56 fixes the truncation of non-literal keys being hashed by MD5.

--

Re: (#2) Base85

Aliases at the end shows how base85 would work. The alias by default should be compatible with Python's a85encode. Python also has a b85encode that's a little friendlier to mIRC script evaluations, but I've included a $3 == 1 variant using an alphabet that should be much more compatible with avoiding mIRC scripting evaluations due to strings containing comma $ % unmatched parenthesis, etc.

Base85 has an advantage over mime, because it has a much smaller encoding overhead, and the lengths of Blowfish encrypted strings will always be a multiple of of base85's input chunk size of 4, while 1/3rd of mime strings would have padding added to their string lengths.

Code
alias unsafe85 { returnex $!base85decode( $+ $base85encode($1,,1) $+ ,,1) }


Using this unsafe85 alias, there could be a .prop or 2nd parameter of $unsafe which makes it use shorter base85 A=1 strings instead of mime:

//timertest85 1 1 echo -a $unsafe85( $ $+ version ) | timertest85

=+=+=+=+=+=
Code
/*
{
  Base85 encoder and decoder by maroon 2019

  85 is used as the base because it's the smallest integer where N^5 >= 256^4, so the
  benefit of base85 over mime is that it can encode 4 bytes into 5 text, for a 125% output length,
  compared to the 133% length where mime encodes 3 bytes as 4 text. When encoding a binary string
  of length 280 bytes, the base85 encoding would be *5/4=350 bytes - while the mime encoding would be
  *4/3=374 bytes plus often being padded with an additional 2 '=' characters.

  There are several encoding alphabets used, and this alias defaults to use the choice by the base85
  in the btoa utilities, Python's a85encode, and in Adobe.

  This alias also offers a $3 == 1 alternate alphabet that's more friendly to mIRC scripting

  Base85 string should not need padding, as the decoded length is calculated from the encoded length. The python
  a85encode has a switch to pad the input string with 0x00's to make it be a length multiple of 4, which also
  eliminates the need for padding, and is friendly to decoded text strings which usually don't need the padding.

  Syntax: $base85encode(any string,N,A) $base85decode(base85text,N,A)
  N: If $2 is 1: $1 is name of &binvar, otherwise $1 is text
  A: If $3 is 1: input/output uses mIRC-friendly alphabet, otherwise uses Ascii85 as described
  at https://en.wikipedia.org/wiki/Ascii85

  examples:
  //echo -a $base85encode(maroon) vs $base85encode(maroon,,1)
  //var -s %a $base85encode(maroon) , %b $base85decode(%a)
  //var -s %a $base85encode(maroon,,1) , %b $base85decode(%a,,1)
  //bset -tc &v 1 maroon | noop $base85encode(&v,1) | echo -a $bvar(&v,1-).text

  The standard base85 encoding originating as one of the methods in btoa, and is as described
  for a85encode at https://docs.python.org/3/library/base64.html#base64.a85encode

  Python's b85encode appears to be the one used by Git diffs, and differs by not using the 'y' 'z' shortcuts
  and uses a different alphabet:

  0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~
  which excludes: "',.:/[\]

  Neither of these is an 85 character alphabet that's completely friendly to mIRC scripting due to using
  characters like " , $ % etc - so care must be taken with strings encoded in the default alphabet.
  Such as avoiding placing them into a timer's command line.

  The A=1 option's mIRC-friendly 85-item alphabet instead excludes these 9 printable chars: "$%'(),:\
  then uses : as the rarely used 'z' symbol which symbolizes an input 4-byte chunk of 4 0x00's
  then uses ' as the rarely used 'y' symbol which symbolizes an input 4-byte chunk of 4 0x20 spaces

  These 'y' and 'z' symbols may be useful in many binary or text strings,
  but are not likely to appear in an encrypted string.

  $3's A=1 mIRC-friendly alphabet attempts to exclude characters which tend to cause problems being evaluated
  by scripts and timers. Most importantly avoids $ and %. Avoiding " allows string inside $qt() and $noqt()
  and skipping \ avoids problems in $reg*() strings. Skipping ) and ( and comma avoids problems trrying to place
  a literal string having unmatched parenthesis or comma inside an identifier without first parking in a %var.
}
*/

; I'm not attached to this specific A=1 alphabet, but it avoids being evaluated in scripts, timers, etc
alias base85_mirc_friendly_alphabet {
  return !#&*+-./0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~
}

/*
{
  If you want to change to a different A=1 alphabet, such as b85encode, by using different characters
  or rearranging them:

  After changing the above alias, the below lookup MUST be created to match the above 85-char string of
  base85_mirc_friendly_alphabet. It creates a bogus entry 99 for invalid characters, and intentially avoids
  an entry for $chr(0) to avoid the need for a $calc(value-1) in an array where the 1st item is array[1] not array[0].

  If $chr(N) is a valid encoding character, the Nth token in the lookup below contains the 0-84 value
  matching items 1-85 in the above list. If the Nth token of the lookup table is anything outside the
  range 0-84, that char is invalid as a base85 encoding character. The numbers 0-84 MUST appear only
  1 time in the lookup below. Also, the : or ' replacements for the standard btoa's 'z' and 'y' symbols being found
  anywhere except the 1st character of an encoding 'chunk' should be invalid, which is why the lookup
  table informs that : and ' are invalids encoding chars.

  After changing the above A=1 alphabet, run: //create_lookup85 $base85_mirc_friendly_alphabet

  then validate the new alphabet:

  //bset -t &v 1 $base85_mirc_friendly_alphabet $+ aaa | echo 3 -a $bvar(&v,1-).text should match | noop $base85decode(&v,1,1) | noop $base85encode(&v,1,1) | echo 4 -a $bvar(&v,1-).text

  Rather than finding 'z' or ':', and 'y' or "'", in a lookup, those are currently hardcoded into the aliases.
}
*/
alias mirc_friendly_base85decode_lookup {
  ; '0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
  var %base85_lookup $&
    99    99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99  0 99  1 99 99  2 99 99 99  3  4 99  5  6  7 $&
    8   9 10 11 12 13 14 15 16 17 99 18 19 20 21 22 $&
    23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 $&
    39 40 41 42 43 44 45 46 47 48 49 50 99 51 52 53 $&
    54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 $&
    70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 $&
    99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
  return %base85_lookup
}

alias create_lookup85 {
  var %a $1
  if ($len(%a) != 85) { var %err input MUST be length 85: $1 | goto create85_err }
  if ($regex(foo,$1,/(.).*\1/)) { var %err input MUST not contain dupes: $regml(foo,1) $1 | goto create85_err }
  if ($regex(foo,$1,/([^!-~])/u)) { var %err input MUST not contain outside range !-~: $regml(foo,1) $1 | goto create85_err }
  bset -c &maroon.tmp 1 $str(99 $chr(32),255)
  var %i 85 | while (%i) { var %a $asc($mid($1,%i,1)) | dec %i | bset &maroon.tmp %a %i }
  echo 3 -a $bvar(&maroon.tmp,1-) existing checksum: $crc( $bvar(&maroon.tmp,1-) ,0)
  echo 4 -a $mirc_friendly_base85decode_lookup new checksum: $crc( $mirc_friendly_base85decode_lookup ,0)
  echo -a To use this 85char alphabet as the new A=1 alphabet, (1) paste the following alias above the existing same name alias:
  echo 3 -a alias mirc_friendly_base85decode_lookup $chr(123) return $bvar(&maroon.tmp,1-) $chr(125)
  echo -a (2) if using a different symbol than ':' in place of input chunk of 4 0x00's, search both base85encode and base85encode aliases for "A=1" and edit as instructed. Should NOT be part of 85-char list
  return
  :create85_err
  echo -sc info *create_lookup85: %err
  echo -sc info syntax: input = string of non-duplicated 85 characters in range ! through ~
}

alias base85encode {
  if ($2 == 1) { if (!$bvar($1,0)) { var %err invalid binvar $1 | goto base85_encode_error }
  bcopy -c &maroon.base85.in 1 $1 1 -1 }
  else noop $regsubex(foo,$1,,,&maroon.base85.in)
  var %in.ptr 1 , %chop 0 , %len $bvar(&maroon.base85.in,0) , %base85.output
  if (!%len) {
    :base85encode_bad_input
  var %err zero length input string | goto base85_encode_error }

  while (%in.ptr <= %len) {

    var %remain $calc(%len - %in.ptr +1)

    ; if at least 4 bytes remaining in input string, check if the 4 bytes at the beginning of a
    ; chunk of 4 are all 0x00 bytes. If so, output a single 'z' (or its mIRC-friendly replacement ':')
    ; ditto for output a 'y' if the chunk of 4 is all $chr(32) spaces.
    ; base85 translates 4 bytes into 5 text, so it's efficient to handle as if it's translating
    ; the 4-byte input chunk as if it's a big-endian unsigned 32-bit integer
    var %uint32 $bvar(&maroon.base85.in,%in.ptr).nlong

    ; at the beginning of each full chunk, check if it's 4 0x00's or 4 0x20's
    ; if customizing $3 A=1 to use a different alphabet, make sure these 2 chars on the ($3 == 1) lines
    ; aren't in the new alphabet, but are the replacements for the 'z' and 'y' shortcuts:

    if ((%remain >= 4) && ($istok(0 538976288,%uint32,32))) {
      if (!%uint32) {
        if ($3 == 1) var -p %base85.output %base85.output $+ :
        else         var -p %base85.output %base85.output $+ z
      }
      else {
        if ($3 == 1) var -p %base85.output %base85.output $+ '
        else         var -p %base85.output %base85.output $+ y
      }

      ; if chunk of 4 is all 0x00's or all 0x20's, then write 'z' or 'y' (or ':' vs "'") only
      goto next_group_of_4
    }

    ; If final input chunk's length wasn't 4, append missing N of 4 bytes as 0x00's, but keep track
    ; so the same number of chars can be stripped from text output
    ; This appends 3 0's to ensure .nlong doesn't fail, but sets %chop to the actual number of
    ; 0's needed to make the final input chunk be length 4
    if (%remain isnum 1-3) {
      var %chop 4 - $v1 | bset &maroon.base85.in $calc(1+%len) 0 0 0
      ; re-defining %uint32 using the appended 0x00's
      var %uint32 $bvar(&maroon.base85.in,%in.ptr).nlong
    }

    var %j 0 , %divisor 85 ^ 4 | while (%j < 5) {
      inc %j
      ; by repeatedly floor-dividing by a shrinking divisor, has the effect of outputting the
      ; encoding digits in the expected big-endian order
      var %pos $calc(%uint32 // %divisor) , %uint32 $calc(%uint32 - %divisor * %pos) , %divisor %divisor / 85

      ; when using sequential base85 alphabet, don't need lookup table
      ; chosen divisor always returns the modulo result in big-endian order
      ; var -p handles case where encoding alphabet contains double-quote char which isn't a good idea
      if ($3 == 1) var -p %base85.output %base85.output $+ $mid($base85_mirc_friendly_alphabet,$calc(1+%pos),1)
      else         var -p %base85.output %base85.output $+ $chr($calc(33 + %pos))
    }
    :next_group_of_4
    inc %in.ptr 4
  }
  ; if added 1-3 0x00 bytes to complete a final chunk of 4, chop that many chars from text output
  ; because encoding length for 1-4 byte chunks is always 1+input_chunk_length
  if (%chop) var -p %base85.output $left(%base85.output,- $+ %chop)

  ; If N=1, replace original &binvar's contents and change return value to new &binvar length
  if ($2 == 1) { bset -tc $1 1 %base85.output | var %base85.output $bvar($1,0) }
  return %base85.output
  :base85_encode_error
  echo -sc info *base85encode: %err
  if ($2 == 1) bunset $1
  ; your choice whether to /halt at error, but would need to decide how to handle binvar
  halt
}

alias base85decode {
  var %last.char u , %in.ptr 1 , %out.ptr 1 , %chop 0 , %4zeroes.char z , %4spaces.char y

  if ($2 == 1) { if (!$bvar($1,0)) { var %err invalid binvar $1 | goto base85_decode_error }
    ; need to unset binvar to facilitate handling contents being 1 valid/invalid base85 char
    else { var %from.string $bvar($1,1-).text | bunset $1 }
  }
  else var -p %from.string $1
  var %len $len(%from.string) | if (!%len) { var %err zero length base85 string | goto base85_decode_error }

  if ($3 == 1) {
    ; if customizing $3 A=1 to use a different alphabet, make sure %4zeroes.char and %4spaces.char on next line
    ; aren't in new alphabet. They are the replacements for the 'z' and 'y' shortcuts
    var %last.char $right($base85_mirc_friendly_alphabet,1) , %4zeroes.char : , %4spaces.char '
    bset -c &maroon.base85.lookup 1 $mirc_friendly_base85decode_lookup
  }

  bunset &maroon.base85.out
  while (%in.ptr <= %len) {
    var -p %this_char $mid(%from.string,%in.ptr,1) , %uint32 0 , %j 0

    ; if 1st byte of chunk is 'z' or 'y' (or ':' or "'" if $3 == 1) then 'z' decode as 4 0x00 bytes
    ; using %uint32 == 0, or 'y' decodes to 4 spaces with %uint32 = $base(20202020,16,10)

    if (%this_char === %4zeroes.char) { inc %in.ptr                         | goto next_group_of_5 }
    if (%this_char === %4spaces.char) { inc %in.ptr | var %uint32 538976288 | goto next_group_of_5 }

    ; if length mod 5 is 1, that final char has no effect so would be safe to ignore
    ; other than validating if it's a valid base85 char
    ;   if (%len == %in.ptr) { dec %len | break }

    ; append %last.char 'u' padding if final group of 5 isn't complete (or append ~ if A=1 $3 == 1)
    ; but keep track of how many chars were added, so that same length can be removed from output
    if ($calc( %len - %in.ptr) < 4) { inc %chop $calc(4+%in.ptr -%len)
      var %from.string %from.string $+ $str(%last.char,%chop)
    }

    while (%j < 5) {
      ; for the default variant using the sequential alphabet, doesn't need the lookup table
      ; because it's a simple calculation by subtracting 33 from $asc(char)
      ; it's much faster to keep the lookup table in a binvar than a text string
      if ($3 == 1) var %s $bvar(&maroon.base85.lookup,$asc($mid(%from.string,%in.ptr,1)))
      else         var %s $asc($mid(%from.string,%in.ptr,1)) - 33

      ; switched to checking for invalid chars here, to simplify the handling of requiring 'z'
      ; appear only at the beginning of a chunk
      if (%s !isnum 0-84) { var %err invalid base85 string | goto base85_decode_error }

    var %uint32 $calc(%uint32 * 85 + %s ) | inc %j | inc %in.ptr }

    :next_group_of_5
    ; cheating by using $longip instead of looping 4x to parse 32-bit value into 4 big-endian byte values
    bset &maroon.base85.out %out.ptr $replace($longip(%uint32),.,$chr(32)) | inc %out.ptr 4
  }

  ; if final block was padded with 1-4 %last.char's, now chop that many extra decoded bytes
  ; because decoded output length == (1 less than input base85 chunk length)
  ; at same time, subtract 1 so %out.ptr = length of output
  var %out.ptr $calc(%out.ptr - %chop -1)
  ; Length of the decoded string is calculated from the length of the encoded string. Also, there's not many un-used chars remaining...

  ; debug output in 3 format types, numeric bytes, hex bytes, text
  ;echo 3 -a bindec: $bvar(&maroon.base85.out,1,%out.ptr)
  ;echo 5 -a binhex: $regsubex(foo,$bvar(&maroon.base85.out,1,%out.ptr),/(\d+)/g,$base(\1,10,16,2))
  ;echo 4 -a text: $bvar(&maroon.base85.out,1,%out.ptr).text

  if ($2 == 1) {
    if (%out.ptr) bcopy -c $1 1 &maroon.base85.out 1 %out.ptr
    else noop $regsubex(foo,$null,,,&maroon.base85.out)
    return %out.ptr
  }
  returnex $bvar(&maroon.base85.out,1,%out.ptr).text
  ; input string was exactly 1 base85 char, so return $null
  return $null
  :base85_decode_error
  echo -sc info *base85decode: %err
  ; input binvar already zeroed, so no need to delete it even if /halt removed
  halt
}

; debugging strings
; test vector at Wikipedia's base85 page for the adobe variant which doesn't use 'y' or 'z' shortcuts:
;//var %a 9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>Cj@.4Gp$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,O<DJ+*.@<*K0@<6L(Df-\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKYi(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIal(DId<j@<?3r@:F%a+D58'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G>uD.RTpAKYo'+CT/5+Cei#DII?(E,9)oF*2M7/c | echo -a $base85decode(%a)
;//var %i 111 | while (%i) { bset -c &v 1 $regsubex($str(x,$rand(40,43)),/x/g,$r(0,255) $chr(32)) | var %a $bvar(&v,1-) , %b $base85encode(&v,1,) , %c $base85decode(&v,1,) , %d $bvar(&v,1-) | if (%a !== %d) echo -a %i diff %a vs %d | ;else echo -a %i same %a  as %b $bvar(&v,1-) | dec %i } | echo -a .
;//var %i 111 | while (%i) { var %a $regsubex($str(x,$r(40,43)),/x/g,$r(a,z)) , %b $base85encode(%a,,1) , %c $base85decode(%b,,1) | if (%a !== %c) echo -a %i diff %a vs %c | ;else echo -a %i same %a  as %c  | dec %i } | echo -a .
;//echo -a ----- | bset -c &v 1 97 97 98 99 32 32 32 32 99 | echo -a $bvar(&v,1-).text | noop $base85encode(&v,1) | echo 3 -a $bvar(&v,1-).text | echo 4 -a $base85decode( $bvar(&v,1-).text ) | echo noop $base85decode(&v,1) | echo -a $bvar(&v,1-)

3 510 Read More
Scripts & Popups Jump to new posts
Re: WEATHER.PPA - Addon for Peace and Protection 4.22 kap 14 hours ago
As it stands I have no plans to change functionality.

Having said that, I still need to have a look at and change the sunrise and sunset eta times, because when negative numbers are returned, the calculation is not right. (= me being a spoon)
2 62 Read More
Feature Suggestions Jump to new posts
Re: Build mIRC with /guard:cf afterdeck Yesterday at 01:31 PM
If anyone is curious, here is the working set of "mitigation options"; tested on Win 10 10362.

Code
<?xml version="1.0" encoding="UTF-8"?>
<MitigationPolicy>
  <AppConfig Executable="mirc.exe">
    <DEP Enable="true" EmulateAtlThunks="false" />
    <ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" />
    <StrictHandle Enable="true" />
    <ExtensionPoints DisableExtensionPoints="true" />
    <DynamicCode BlockDynamicCode="true" AllowThreadsToOptOut="false" Audit="false" />
    <ControlFlowGuard Enable="true" SuppressExports="false" />
    <SignedBinaries MicrosoftSignedOnly="true" AllowStoreSignedBinaries="false" Audit="false" AuditStoreSigned="false" EnforceModuleDependencySigning="true" />
    <Fonts DisableNonSystemFonts="true" AuditOnly="false" Audit="false" />
    <ImageLoad BlockRemoteImageLoads="true" AuditRemoteImageLoads="false" BlockLowLabelImageLoads="true" AuditLowLabelImageLoads="false" />
    <Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" />
    <SEHOP Enable="true" TelemetryOnly="false" />
    <Heap TerminateOnError="true" />
    <ChildProcess DisallowChildProcessCreation="true" Audit="false" />
  </AppConfig>
</MitigationPolicy>
3 99 Read More