Better random (unique) file name
It might be best to use CreateUUID
.
CreateUUID[]
"73ccc27c-687f-4eca-8214-ceeb8a8b7773"
The Properties & Relations section shows a way to express this string as an integer if that's what you're after:
FromDigits[StringReplace[CreateUUID[], "-" -> ""], 16]
296740835687065620982102887154699649600
This should give you strings that are unique. It uses $SessionID
and $ProcessID
which are a unique combination by definition, either hashed (almost unique) or plain (unique by design).
Short name, almost unique.
Hash
in "Base36String"
to keep the string short (28 characters). It has the date and $KernelID
in plain text for easy identification.
StringJoin[
Riffle[
{
Hash[{$SessionID , $ProcessID}, "CRC32", "Base36String"],
DateString[{"Year", "MonthNameShort", "Day", "Hour24", "Minute",
"Second", "MillisecondShort"}],
ToString[$KernelID]
}, "-"]
]
"02y4q0o-2019Jul04180113431-0"
The probability of collision for a "CRC32"
hash is extremely low, $(n - 1) / 2^{32}$ and way better than your $(n - 1) / 10^5$, and occurring at the same time (within a millisecond) and in the same kernel is in practical terms imposible.
Long names, absolutely unique
If you can afford extremely long names, you could leave $SessionID
and $ProcessID
unhashed.
You can shorten the string length also using IntegerString
with "Base64"
encoding.
StringJoin[
Riffle[
Flatten@{
StringDelete[
IntegerString[{$SessionID , $ProcessID}, "Base64"], {"+", "/",
"="}],
DateString[{"Year", "MonthNameShort", "Day", "Hour24", "Minute",
"Second", "MillisecondShort"}],
ToString[$KernelID]
}, "-"]
]
Otherwise use them to define folder (directory) names.
FileNameJoin[
ToString /@ {
$MachineName,
$SessionID ,
$ProcessID,
DateString[
{"Year",
"MonthNameShort",
"Day",
"Hour24",
"Minute",
"Second",
"MillisecondShort"
}]
}
]