Just nu i M3-nätverket
Jump to content

Omvandla en siffra till en bokstavskombination.


Erik Junesjö

Recommended Posts

Erik Junesjö

Hej!

Jag har på skoj skapat sidan http://surl.se . Där kan man skapa korta länkar av långa.

 

Idag gör jag så att jag lägger in länken i databasen och får ut identityt, tex http://surl.se/669 .

 

Om tillräckligt många in sina länkar så kommer nummret att bli väldigt långt. Jag skulle därför vilja ha en funktion för att omvandla siffror till bokstavskombinationer.

 

Finns det någon möjlighet att lösa detta matematiskt?

 

//Erik

 

 

[inlägget ändrat 2004-11-05 16:22:01 av Erik Junesjö]

Link to comment
Share on other sites

Gör om det till hexadecimala tal kanske? Eller ett talsystem med ännu högre bas.

 

Borde inte det fungera shysst, visserligen ville du bara ha bokstäver som jag förstår det. Det blir även siffror med i dessa... vilket kanske därför inte besvarar din fråga.

 

 

Shysst idé föressten!

[inlägget ändrat 2004-11-05 16:38:12 av Sasja]

Link to comment
Share on other sites

Erik Junesjö
Gör om det till hexadecimala tal kanske? Eller ett talsystem med ännu högre bas.

 

Borde inte det fungera shysst, visserligen ville du bara ha bokstäver som jag förstår det. Det blir även siffror med i dessa... vilket kanske därför inte besvarar din fråga.

Bra ide, det är helt ok med siffror i fältet bara det blir så kort som möjligt.

 

Känner du till något talsystem med högre bas än det hexadecimala?

 

Jag skulle vilja utnyttja 0-9 och a-z.

//Erik

 

 

[inlägget ändrat 2004-11-05 16:43:13 av Erik Junesjö]

Link to comment
Share on other sites

Tja, enklast är väl:

A=1

B=2

C=3

osv till Z = 26

 

Är det även möjligt att skilja på stora och små bokstäver har du 26 värden till.

 

Sedan är det bara att räkna, intressant med en bas på 52.... (ed: lägg till 0 -9 och du har en bas på 36 eller 62. Inte illa)

 

Inte för att länkarna blir lätta att komma ihåg direkt.

 

Enklast är väl om du säger att du har en nummerserie på, låt oss säga, 10 000 länkar. Lägg till ett bokstavsprefix och du har tillgång till 26 000 länkar. Två prefix 26x26 * 10 000 länkar.

 

/T

 

Even when we know we´ll never find the answers, we have to keep on asking questions.

 

[inlägget ändrat 2004-11-05 16:46:50 av Monshi]

hoppsan, w och v finns visst båda.

 

[inlägget ändrat 2004-11-05 16:49:02 av Monshi]

Link to comment
Share on other sites

Känner du till något talsystem med högre bas än det hexadecimala?

 

Kan inte namnet på dom. Men du kan ju i princip använda ett talsystem som är lika med antalet tecken man kan ha i en url. Ett talsystem med basen 36 om servern din inte känner skillnad på gemener och versaler. Om servern känner skillnad på dessa kan man ha en bas på 26*2+10=52.

 

Tar då med tecknena a-z, A-Z, 0-9.

 

Är inte säker, men en del servrar känner väl skillnad på gemener och versaler och andra inte? Am I right?

 

Link to comment
Share on other sites

1. Säg att du vill omvandla talet T till bokstavslänk.

 

2. Gör en lista över de tecken du vill använda (stora och små bokstäver t ex). Säg att listan blir 56 tecken lång.

 

3. Beräkna R = T modulo 56. (modulo = resten vid heltalsdivision)

 

4. Plocka ut tecken R ur listan och addera det till länken.

 

5. Låt T' = T / 56. (/ = heltalsdivision)

 

6. Om T' > 0, låt T = T' och gå tillbaka till steg 3.

 

[inlägget ändrat 2004-11-05 16:53:42 av lizardKng]

Link to comment
Share on other sites

Man kan konstruera sina egna talsystem på de mest märkliga vis.

 

Att räkna modulo ett heltal är bara det enklaste sättet.

 

Numera kan man utan problem konstruera "talsystem" "modulo" en mängd polynom. Denna generalisering blev möjlig genom skapandet av Gröbnerbaser. Gröbnerbaser gör det möjligt att räkna med polynom som om de vore vanliga tal.

 

Gröbnerbaser används t ex för att lösa polynomekvationer på samma sätt som man löser linjära ekvationssystem och inom kodningsteori för att nämna två exempel.

[inlägget ändrat 2004-11-05 18:07:50 av lizardKng]

Link to comment
Share on other sites

Många försök att uppfinna hjulet på nytt här =)

Jag säger som Mr Andersson, använd Base64 istället, beprövad och enkel algoritm. Du måste förstås först dela upp ditt tal i grupperingar om 3 bytes om jag minns rätt, men det är ju en lätt operation.

 

Hursomhelst, en kul och smart idé tycker jag att du har där Erik. Varför har man inte sett mer sånt på nätet?

 

Link to comment
Share on other sites

  • 2 weeks later...
Erik Junesjö

Det fíck bli en vbfunktion.

[log]

function getNextLetterStr(strShortLink)
strShortLink = UCASE(strShortLink)
dim arrLetters, lenShortLink, i, dicShortLink, itemLetters, intCountLetters
dim intCutLetterIndex, bolAddLetter, strNewShortLink, bolAddFinished, strCutLetter

set dicShortLink = CreateObject("Scripting.Dictionary")
dicShortLink.add "A","1"
dicShortLink.add "B","2"
dicShortLink.add "C","3"
dicShortLink.add "D","4"
dicShortLink.add "E","5"
dicShortLink.add "F","6"
dicShortLink.add "G","7"
dicShortLink.add "H","8"
dicShortLink.add "I","9"
dicShortLink.add "J","10"
dicShortLink.add "K","11"
dicShortLink.add "L","12"
dicShortLink.add "M","13"
dicShortLink.add "N","14"
dicShortLink.add "O","15"
dicShortLink.add "P","16"
dicShortLink.add "Q","17"
dicShortLink.add "R","18"
dicShortLink.add "S","19"
dicShortLink.add "T","20"
dicShortLink.add "U","21"
dicShortLink.add "V","22"
dicShortLink.add "W","23"
dicShortLink.add "X","24"
dicShortLink.add "Y","25"
dicShortLink.add "Z","26"

arrLetters = dicShortLink.Keys
itemLetters= dicShortLink.Items

intCountLetters = ubound(arrLetters) + 1

lenShortLink = len(strShortLink)

bolAddFinished = false
bolAddLetter=false
i = len(strShortLink)

strNewShortLink = ""

while i > 0
	intCutLetterIndex =  int(dicShortLink.item(mid(strShortLink,i,1)))

	if intCutLetterIndex=intCountLetters and not bolAddFinished then
		strCutLetter = arrLetters(0)
	elseif not bolAddFinished then
		strCutLetter = arrLetters(intCutLetterIndex)
		bolAddFinished = true
	elseif bolAddFinished then
		strCutLetter = arrLetters(intCutLetterIndex-1)
	end if

	strNewShortLink = strCutLetter & strNewShortLink

	i = i-1
wend

if bolAddFinished = false then
	strNewShortLink = strNewShortLink & "A"
end if
getNextLetterStr = strNewShortLink
end function

response.write getNextLetterStr("ABCDEF")

[/log]

Kanske inte världens snyggaste men det fungerar.

//Erik

 

Link to comment
Share on other sites

Testa den här Erik. Snabbt ihopskriven, men den bör göra samma sak:

 

function NextLetterStr(s) 
for i=len(s) to 1 step -1
	n1=(asc(mid(s,i,1))-63) 
	n2=n1 mod 26 
	c=chr(n2+64) & c
	if n2=n1 then exit for
next
if i=0 then c="A" & c
for j=i-1 to 1 step -1
	c=mid(s,j,1) & c
next
NextLetterStr=c
end function

 

Link to comment
Share on other sites

Har testat igenom funktionen nu och den ger faktiskt exakt samma resultat, så i form av kompakt kod blev den ju snäppet snyggare. Skrev om den med lite mer meningsfulla variabler:

 

Function NextLetterStr(strShortLink) 
For i=Len(strShortLink) To 1 Step -1
	nNextOrdinal=(Asc(Mid(strShortLink,i,1))-63) 
	nMutadedOrdinal=nNextOrdinal Mod 26 
	sNewLink=Chr(nMutadedOrdinal+64) & sNewLink
	If nMutadedOrdinal=nNextOrdinal Then Exit For
Next
If i=0 Then sNewLink="A" & sNewLink
For j=i-1 To 1 Step -1
	sNewLink=Mid(strShortLink,j,1) & sNewLink
Next
NextLetterStr=sNewLink
End Function

 

Link to comment
Share on other sites

Erik Junesjö
Testa den här Erik. Snabbt ihopskriven, men den bör göra samma sak:
Tack Anjuna. Nu slipper jag skapa ett dictionaryobjekt. Snyggt jobbat!

//Erik

 

Link to comment
Share on other sites

Kan du på rak arm säga om man skulle kunna bygga denna funktion i en store procedure?

 

Jag ser ingenting på rak arm som skulle förhindra det, åtminstone är jag ganska säker på att jag kan sätta ihop det i MSSQL, som är den dbms jag själv behärskar bäst. Jag kan göra ett försök lite senare.

 

Link to comment
Share on other sites

Hej igen Erik. Det gick alldeles utmärkt att göra om det till MSSQL. Jag gjorde det till en User-defined function istället, som du kan anropa från dina stored procedures:

 

CREATE FUNCTION fn_NextLetterStr (@strShortLink varchar(200))  

RETURNS  varchar(200)
AS  
BEGIN 
	DECLARE @i int
	DECLARE @nNextOrdinal int
	DECLARE @nMutadedOrdinal int
	DECLARE @sNewLink varchar(200)

	SET @i=LEN(@strShortLink)
	SET @sNewLink=''
	WHILE (@i>0)
		BEGIN
			SET @nNextOrdinal=(ASCII(SUBSTRING(@strShortLink,@i,1))-63) 
			SET @nMutadedOrdinal=@nNextOrdinal % 26
			SET @sNewLink=CHAR(@nMutadedOrdinal+64) + @sNewLink
			IF (@nMutadedOrdinal=@nNextOrdinal)
				BREAK
			ELSE
				SET @i=@i-1
		END
	IF (@i=0) 
		SET @sNewLink="A"  + @sNewLink
	SET @i=@i-1

	WHILE (@i>0)
		BEGIN
			SET @sNewLink=SUBSTRING(@strShortLink,@i,1) + @sNewLink
			SET @i=@i-1
		END
	RETURN (@sNewLink)
END

 

EDIT: Hm, indenteringen försvann förstås

[inlägget ändrat 2004-11-16 16:57:39 av Anjuna Moon]

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.



×
×
  • Create New...