Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Simple function to create unique names


  • Please log in to reply
6 replies to this topic
Paulo
  • Members
  • 28 posts
  • Last active: May 31 2007 12:53 AM
  • Joined: 21 Apr 2006
This function generates unique strings using ASCII codes from 97 to 122 (lowercase a-z) and from 65 to 90 (uppercase A_Z)
I am using it to create unique names for one click file renaming and for download list creation, and I thought that it may interest someone else.

To call the function:
Loop, 2 {
	name := f_BuildNames("x",5)
	Loop, 3
		msgbox,  %name%-%A_Index%
}
; "x" may be any letter ("r" for rename "d" for download...), 5 = length of string (not greater than 10)
; this code limits the returned string to 10 chars(max).I think it is much more than enough.
; 5 chars will produce 26*26*26*26*26 unique strings

the function:
f_BuildNames(x,n) {
	IniRead, v_positions, buildnames.ini, ASCII_values, key%x%%n%, 97|97|97|97|97|97|97|97|97|97 ;there is no problem if file|section|key does not exist
	StringSplit, p, v_positions, |
	Loop, %n% {
		i := Mod(1+n- A_Index,n+1)

                  ; in the first run i = n, second i = n - 1 ...last i = 1

		v_name := chr(p%i% - 32 * Mod(p%n% - Mod( A_Index + 1,  A_Index),2)) . v_name

      ;this line builds a string (aaa...a to zzz...z) and toggles lower and
		;- upper case (AAAAA aaaab AAAAC aaaad...)
		;- inner mod() returns "0" if A_Index = 1 and "1" if A_Index > 1 it is needed because "n" of p%n% will be "n + 1" after the first loop iteration
		;- outer mod(expression,2) returns "0" if evaluated expression = even number or "1" if uneven, returned value is used to define if "v_name" will be upper or lowercase
		;- so chr(expression) will evaluate for example "97 - 32" retuning "A" or "97 - 0" returning "a"


		;v_name := chr(p%i%) . v_name ;uncomment this line and comment|delete the previous if you don't want to switch lower/uppercase


		If (p%i% < 122 && v_stop != 1) {
			p%i% ++  ;if char is not yet "z" increase p%i% value
			v_stop = 1 ; stop checking otherwise all p%i% values will be increased
		}
		Else If (p%i% > 121 && v_stop != 1) ;ASCII 122 = lowercase "z"
			p%i% = 97 ;reset to "a"
	}
	IniWrite, %p1%|%p2%|%p3%|%p4%|%p5%|%p6%|%p7%|%p8%|%p9%|%p10%, buildnames.ini, ASCII_values,key%x%%n%
	; since this script will run "n" loop iterations I decided to not mount the value for "IniWrite" inside the loop
	Return, v_name
}


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
You could also use the time (A_Now, maybe with A_MSec) as a unique filename. There is no need for an ini file or for a loop to enforce uniqueness. If you want to be sure, that no other process created a conflicting filename, check if a file exists with the new name. If yes, try it again. The time increases, and eventually you will find an unused name.

BoBo
  • Guests
  • Last active:
  • Joined: --
Thought it'll make sense to do some cosmetical changes to clearly separate the comments from the code :roll:
f_BuildNames(x,n) { 

   IniRead,v_positions,buildnames.ini,ASCII_values,key%x%%n%,97|97|97|97|97|97|97|97|97|97

   ;there is no problem if file|section|key does not exist

   

   StringSplit, p, v_positions, | 

   Loop, %n% { 

      i := Mod(1+n- A_Index,n+1)

      ; in the first run i = n, second i = n - 1 ...last i = 1



      v_name := chr(p%i% - 32 * Mod(p%n% - Mod( A_Index + 1,  A_Index),2)) . v_name

      ; this line builds a string (aaa...a to zzz...z) and toggles 

      ; lower and upper case (AAAAA aaaab AAAAC aaaad...) 

      ; inner mod() returns "0" if A_Index = 1 and "1" if A_Index > 1 it is needed because "n" of p%n%

      ; will be "n + 1" after the first loop iteration outer mod(expression,2) returns "0" if evaluated

      ; expression = even number or "1" if uneven, returned value is used to define if "v_name" will be

      ; upper or lowercase so chr(expression) will evaluate for example 

      ; "97 - 32" returning "A" or "97-0" returning "a" 

      

      v_name := chr(p%i%) . v_name

      ;uncomment this line and comment|delete the previous if you don't want to switch lower/uppercase 



      If (p%i% < 122 && v_stop != 1) { 

         p%i% ++  ;if char is not yet "z" increase p%i% value 

         v_stop = 1 ; stop checking otherwise all p%i% values will be increased 

      } 

      Else If (p%i% > 121 && v_stop != 1) ;ASCII 122 = lowercase "z" 

         p%i% = 97 ;reset to "a" 

   } 

   IniWrite,%p1%|%p2%|%p3%|%p4%|%p5%|%p6%|%p7%|%p8%|%p9%|%p10%,buildnames.ini,ASCII_values,key%x%%n%

   ; since this script will run "n" loop iterations I decided

   ; to not mount the value for "IniWrite" inside the loop 

   Return, v_name 

}


BoBo
  • Guests
  • Last active:
  • Joined: --
:shock: GOSH. My editing hasn't worked out! Grrrrrrrrrr ... :evil:

Paulo
  • Members
  • 28 posts
  • Last active: May 31 2007 12:53 AM
  • Joined: 21 Apr 2006

GOSH. My editing hasn't worked out! Grrrrrrrrrr ...

I tried too...

You could also use the time (A_Now, maybe with A_MSec) as a unique filename

I prefer (almost need) short and easily identifiable filenames like aaaaa-01 aaaaa-02 to help me to recognize group of files, inside a listview with hundreds or thousands img files, so numeric filenames doesn't work well for me.And because of this I am also switching upper/lowercase.

Micha
  • Members
  • 539 posts
  • Last active: Dec 31 2011 01:43 PM
  • Joined: 15 Nov 2005
Hi,
there's a system-function you can use. Please have a look at
http://msdn.microsof...empfilename.asp
for the weird syntax (unique switch).

If unique = 0 a file is created
if unique <> 0 only the filename is returned.

Here's an example
nUnique = 0
VarSetCapacity(szFilename, 1000)

nRC := DllCall("GetTempFileNameA", str, PathName, str, Prefix, int, nUnique, str, szFilename, "Cdecl Int")
if (errorlevel <> 0) || (nRC = 0)
{
	MsgBox error while calling GetTempFileNameA Errorlevel: %errorlevel% - RC: %nRC%
	return
}
MsgBox, The Filename is: %szFilename%
Prefix=PREFIX ;Only the 3 first letters are used !!!
nRC := DllCall("GetTempFileNameA", str, PathName, str, Prefix, int, nUnique, str, szFilename, "Cdecl Int")
if (errorlevel <> 0) || (nRC = 0)
{
	MsgBox error while calling GetTempFileNameA Errorlevel: %errorlevel% - RC: %nRC%
	return
}
MsgBox, The Prefix+Filename is: %szFilename%
nUnique = 1
nRC := DllCall("GetTempFileNameA", str, PathName, str, Prefix, int, nUnique, str, szFilename, "Cdecl Int")
if (errorlevel <> 0) || (nRC = 0)
{
	MsgBox error while calling GetTempFileNameA Errorlevel: %errorlevel% - RC: %nRC%
	return
}
MsgBox, The not unique Filename is: %szFilename%

Ciao
Micha

Paulo
  • Members
  • 28 posts
  • Last active: May 31 2007 12:53 AM
  • Joined: 21 Apr 2006
Thanks, Micha.
very interesting function.