The:
set /a smallsec=1%@random::~-2%-100
on second thought is not good as the value of @random may well be <=9 (or a single digit if you prefer) this possibility should be taken into account.
This is not a problem in MAKEUUID.LLL, everything is counted and transformed with the textual approach. Values in the whole 0-99 range are processed, I hope in the right way.
I made a new version, with arguments this time, and I changed the name of the Function to MakeUuidFat. Output-format can be chosen, date/time/hundreth can be added if a certain MS-DOS UUID is wanted.
!BAT
#MAKEUUID.LLL v0.1.3 (20210730), by deomsh
#Generate MS-DOS Volume Serial Number
#Use: MAKEUUID.LLL MakeUuidFat [uuid|write] [year-month-day] [hour:minute:second] [hundreth]
#Mandarory Argument: MakeUuid
#Optional arguments: [uuid|write] [yyyy-mm-dd] [hh:mm:ss] [hundreth] (of seconds - default=0)
#Remarks: Function-name is not case-sensitive. [uuid|write] not case-sensitive, can be left out. If used: date time hundreth only last argument can be left out, their order is NOT free
call :%~1 %*
#echo %~1: result=%result%
goto :eof
:MakeUuidFat
setlocal && set *
if not /i "%~2"=="write" && if not /i "%~2"=="uuid" && set mode=uuid
if /i "%~2"=="write" && set mode=%~2 && shift
if /i "%~2"=="uuid" && set mode=%~2 && shift
set date=%~2
set time=%~3
set smallsec=%~4
if not exist date && set date=%@date%
set /a year=%date:~0,4% > nul
set /a month=%date:~5,2% > nul
set /a day=%date:~8,2% > nul
if not exist time && set time=%@time%
set /a hour=%time:~0,2% > nul
set /a minute=%time:~3,2% > nul
set /a second=%time:~6,2% > nul
if exist smallsec && set /a smallsec=%smallsec% > nul && goto :norandom
beep 0 20 ;; set /a smallsec=%@random:~-2% > nul
:norandom
#echo Date: %day%-%month%-%year% Time: %hour%:%minute%:%second%:%smallsec%
set /A month=%date:~5,2% * 0x100 > nul
set /A second=%time:~6,2% * 0x100 > nul
set /A uuidlow=%month% + %day% + %second% + %smallsec% > nul
set /a llow=%@retval% > nul
set /A hour=%time:~0,2% * 0x100 > nul
set /A uuidhigh=%hour% + %minute% + %year% > nul
set /a lhigh=%@retval% > nul
if %lhigh%==6 && if %llow%==6 && set volumeid=\x%uuidhigh:~4,2%\x%uuidhigh:~2,2%\x%uuidlow:~4,2%\x%uuidlow:~2,2% > nul && set volserial=%uuidlow:~2,2%%%uuidlow:~4,2%%-%uuidhigh:~2,2%%%uuidhigh:~4,2%
if %lhigh%==6 && if %llow%==5 && set volumeid=\x%uuidhigh:~4,2%\x%uuidhigh:~2,2%\x%uuidlow:~3,2%\x0%uuidlow:~2,1% > nul && set volserial=0%uuidlow:~2,1%%%uuidlow:~3,2%%-%uuidhigh:~2,2%%%uuidhigh:~4,2%
if %lhigh%==5 && if %llow%==6 && set volumeid=\x%uuidhigh:~3,2%\x0%uuidhigh:~2,1%\x%uuidlow:~4,2%\x%uuidlow:~2,2% > nul && set volserial=%uuidlow:~2,2%%%uuidlow:~4,2%%-0%uuidhigh:~2,1%%%uuidhigh:~3,2%
if %lhigh%==5 && if %llow%==5 && set volumeid=\x%uuidhigh:~3,2%\x0%uuidhigh:~2,1%\x%uuidlow:~3,2%\x0%uuidlow:~2,1% > nul && set volserial=0%uuidlow:~2,1%%%uuidlow:~3,2%%-0%uuidhigh:~2,1%%%uuidhigh:~3,2%
if %lhigh%==4 && if %llow%==6 && set volumeid=\x%uuidhigh:~3,2%\x0%uuidhigh:~2,1%\x%uuidlow:~4,2%\x%uuidlow:~2,2% > nul && set volserial=0%uuidlow:~1,2%%%uuidlow:~4,2%%-00%uuidhigh:~3,2%
if %lhigh%==4 && if %llow%==5 && set volumeid=\x%uuidhigh:~2,2%\x00\x0%uuidlow:~4,1%\x0%uuidlow:~2,1% > nul && set volserial=0%uuidlow:~2,1%%%uuidlow:~3,2%%-00%uuidhigh:~2,2%
if %lhigh%==3 && if %llow%==6 && set volumeid=\x00\x0%uuidhigh:~2,1%\x%uuidlow:~4,2%\x%uuidlow:~2,2% > nul && set volserial=%uuidlow:~2,2%%%uuidlow:~4,2%%-000%uuidhigh:~2,1%
if %lhigh%==3 && if %llow%==5 && set volumeid=\x00\x0%uuidhigh:~2,1%\x%uuidlow:~3,2%\x0%uuidlow:~2,1% > nul && set volserial=0%uuidlow:~2,1%%%uuidlow:~3,2%%-000%uuidhigh:~2,1%
#echo Volume Serial Number: %volserial%
#echo Volume Serial Number little-endian: %volumeid% (for write FILE %^result%)
if %mode%==uuid && set result=%volserial% ! set result=%volumeid%
endlocal && set result=%result%
goto :eof
BTW: this version should be clean now (only a few echos left, can be activated if desired). I added lines to cope with years closer to 1 AD
After restudying Craig Wilson's 'Volume Serial Numbers' I added his '2003-10-19 22:33:27:1' example, together with use of other arguments in following 'print-screen':
grub> makeuuid.lll makeuuidFAT
date: 30-7-2021 time: 23:51:48:22
Volume Serial Number: 3734-1F18
Volume Serial Number little-endian: \x18\x1F\x34\x37 (for write FILE %result%)
makeuuidFAT: result=3734-1F18
grub>
grub> makeuuid.lll makeuuidFAT write
date: 30-7-2021 time: 23:51:51:74
Volume Serial Number: 3A68-1F18
Volume Serial Number little-endian: \x18\x1F\x68\x3A (for write FILE %result%)
makeuuidFAT: result=\x18\x1F\x68\x3A
grub>
grub> makeuuid.lll makeuuidFAT 2003-10-19 22:33:27 1
date: 19-10-2003 time: 22:33:27:1
Volume Serial Number: 2514-1DF4
Volume Serial Number little-endian: \xF4\x1D\x14\x25 (for write FILE %result%)
makeuuidFAT: result=2514-1DF4
grub>
grub> makeuuid.lll makeuuidFAT write 0001-01-01 00:00:00 0
date: 1-1-1 time: 0:0:0:0
Volume Serial Number: 0101-0001
Volume Serial Number little-endian: \x00\01\x01\x01 (for write FILE %result5)
makeuuidFAT: result=\x00\x01\x01\x01
grub> _
BTW the only strange thing in Craig Wilson's paper is that the MS-DOS UUID isn't written in Litte-Endian in the picture on page 4. I checked again and again, but with uuid --write (hd2,0) 2514-1DF4 I get with cat --hex --skip=0x27 --length=4 (hd2,0)+1 always F4 1D 14 25 ??
I played a bit with uuid's before 1987. After attaching the VHD I used in Vbox with Disk Management, Windows 10 happily found no errors and displayed with DIR in cmd 0101-0001
You can still ADD a 0 in the place of the "optional" (not anymore optional) parameter.
I.e. (in my perverted mind) something *like*:
:CleanMd
call AllFunctions.lll %0 %* 0
goto :eof
could do nicely, if the (optional) parameter is specified on original call, it will be %4 (or %5, unless you use shift to have parameters as in the original call), if it is not specified the trailing 0 will "shift" and take its place.
Although not needed for CleanMd, the idea from your 'perverted mind' 'saved my day' last thursday. I was trying to set several default values in a function to count variables, so without adding variables before all variables are safely in memory. So THANK YOU VERY MUCH. Even your call starting with %0 inspired my to a new argument (starting %0 is not needed in my approach, the function is always %1 before shifting and can be linked endlessly with :%1 %*).
!BAT
#CNTVARS.LLL v0.1 (20210729), by deomsh.
#Function: Count number of variables
#Mandatory Arguments: CntVars
#Optional Arguments: [mdbase sectors %0]
#Remarks: (if used ALL needed: base memory in 512 byte sectors -default=0x3000; needed sectors for maximum number of variables of max length, max 511 sectors - default=60; %0 must be a label or preceding colon must be added)
#debug 0
#echo %*
##call :SubRoutine %*
call :%~1 %* 0x3000 60
#echo Function: %~1 result=%result%
goto :eof
:SubRoutine
#echo %~0 %*
#call :%~1 %* 0x3000 60
call :%~1 %* 0x3000 60 %0
goto :eof
:CntVars
#echo %~0 %*
echo -n > (md)%~2+%~3
set > (md)%~2+%~3
setlocal && set *
echo -n && call Fn.4 ;; set /A r=%@retval% > nul ;; set /a y=%r%>>8 > nul ;; set /a x=%r%&0xFF > nul
cat --locate=\x0A (md)%~2+%~3 > nul ;; set /a result=%@retval% > nul
echo -n > (md)%~2+%~3
:LoopCntVars
set ARG=%~4 &; if not "%ARG%"=="" &; if %ARG:~0,1%==: && set ARG4=%~4 ! shift && goto :LoopCntVars
if exist ARG4 && set "message=Number of variables=%result% in %ARG4%" ! set "message=Number of variables=%result%"
set "message=%message%" ;; set msglen=%@retval% > nul ;; set /a h=79-%msglen% > nul
call Fn.5 %h% 24 || echo -n $[0x0F]%message%
call Fn.5 %x% %y%
#set
endlocal
#endlocal && set result=%result%
goto :eof
BTW, best used with: CNTVARS.LLL CntVars optional arguments && pause. For instance I tested in my editline-project call cntvars.lll CntVars 0x3900 60 %0 && pause to get on the last line shifted to the right: Number of variables=40 in :editline (:editline is the central submenu sub-routine).
BTW2 Of course 60 is overkill, one variable including name and overhead will in the average not come above 20-25 chars, so 3 sectors will do in most cases.
BTW3 Not meant as stand-alone utility. Can be used, but after line 23 only with && pause
Question: I don't see any possibility to make more than one default value (in fact I used one optional argument, consisting of two or three values). Will that be somehow do-able?