Avatar billede exp Juniormester
03. august 2004 - 17:58 Der er 22 kommentarer og
2 løsninger

Generere ikke-så-tilfældig række tegn

Heysan,

står lige og mangler en metode til at generere en række tegn.

Systemet er således:
Det skal egentlig virke lidt ligesom auto_increment i mysql, men med både bogstaver OG tal...

rækkefølgen er a-z 2-9 (følgende (skal kunne ændres) er udeladt: o, 1, l, 0 (nul), samt blokbogstaver)

således at:
efter "a" kommer "b"
efter "b" kommer "c"
[...]
efter "z" kommer "2"
efter "9" kommer "aa"
efter "aa" kommer "ab"
etc
etc
etc

de forskellige kombinationer skal gemmes i en database, og såfremt  der genereres en tegn-kombination der allerede findes i databasen, skal den selvfølgelig springes over, og hoppes videre til den næste frie kombination, ved at følge ovenstående mønster.

Det er lidt svært at forklare - håber i fanger idéen, ellers må i lige spørge :-)


Nogen med de gyldne linier?
Avatar billede krydset Nybegynder
03. august 2004 - 18:36 #1
Jeg har en der virker du kan bare ikke smide tegnrækkefølgfe i den kan den bruges
Avatar billede krydset Nybegynder
03. august 2004 - 19:01 #2
jeg lavede det her engang tror det virker ok



<?php
function make_password() {
    $len = 8;
    mt_srand((double)microtime() * 1000000);
    $pwd = '';

    for($i = 0; $i < $len ; $i++) {
    $num = mt_rand(48, 122);

        if (($num > 96 && $num < 123 ) || ($num > 64 && $num < 91) || ($num > 47 && $num < 58))
            $pwd .= chr($num);
        else
            $i--;
    }

    return $pwd;
}
$antal = 1000;
for ($i=0; $i <= $antal; $i++) {
    $pass = make_password();
   
    //Tjekker om pass findes i databasen
    $db_connect = mysql_connect("localhost", "medieburner", "tils9217") or die(mysql_error());
    mysql_select_db("pass", $db_connect) or die(mysql_error());

    $pass_res = mysql_query("SELECT * FROM pass WHERE pass = '$pass'") or die(mysql_error());
    $pass_antal = mysql_num_rows($pass_res);
   
    if($pass_antal >= 1) {
            $pass = $make_password();
    } else {
        //Indsæt i database
        mysql_query("INSERT INTO pass (pass) VALUES ('$pass')") or die(mysql_error());
    }
}



?>
Avatar billede exp Juniormester
03. august 2004 - 20:36 #3
Det er vigtigt, at det kun er små bogstaver - til nød kan tal udelades, men endnu vigtigere er det, at rækkefølgen holdes.

Altså a, herefter b, c, d, [...] z, aa, ab, ac, ad [...] az, ba, bc, bd [...] zz, aaa, aab, aac und so weiter.
Avatar billede roenving Novice
04. august 2004 - 00:50 #4
Det gælder vel så bare om at lave en ordentlig algoritme ...

Nu hører php jo ikke under mine egenskaber, men her er en javascript-ting, som ikke præcis er optimeret, men jeg regner med at du kan finde ud af at ændre det til php !-)

-- og den er sat i et html-dokument, så det er nemt at checke den for mærkværdigheder:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Lav koder</title>
<meta name="keywords" content="roenving,http://www.eksperten.dk/spm/525946">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
html,body{height:100%;margin:0px;border:0px;padding:0px;font-family:tahoma,verdana,arial,sans-serif;font-size:small;}
</style>
<script language="javascript" type="text/javascript">
var tegn = "abcdefghijkmnpqrstuvwxyz23456789";
var sidsteKode = nyKode = "",actPlads = new Array(),newLength = true;
function lavKoder(a,n){
  switch(lavKoder.arguments.length){
    case 1:
      n = 300;
      break;
    case 0:
      n = 30;
      a = "a";
  }
  sidsteKode=a;
  for(i=0;a.length>i;i++){
    actPlads[i] = tegn.indexOf(a.charAt(i));
  }
  for(i=0;n>i;i++){
    actPlads[a.length-1]++;
    if(actPlads[a.length-1]==tegn.length){
      newLength = true;
      for(j=a.length-1;j>=0;j--){
        if(tegn.length-1>actPlads[j]){
          actPlads[j]++;
          newLength = false;
          break;
        }else{
          actPlads[j] = 0;
        }
      }
      if(newLength){
        actPlads[a.length] = 0;
      }
    }
   
    nyKode = "";
    for(j=0;actPlads.length>j;j++){
      nyKode += tegn.charAt(actPlads[j]);
    }
    document.write(nyKode+", ");
    a = nyKode;
  }
}
</script>
</head>

<body onresize onload>
<div style="width:600px;">
<script type="text/javascript">document.write("9, ");lavKoder("9",4000)</script>
</div>
</body>

</html>
Avatar billede roenving Novice
04. august 2004 - 00:54 #5
-- og jeg fandt ingen mærkværdigheder, da jeg bad den om at lave 40000 koder, bortset fra, at browseren brokkede sig over at javascriptet kørte og kørte og kørte og ...

-- og nej !-) jeg checkede ikke alle 40000 koder, men kiggede en del overgange igennem !o]
Avatar billede exp Juniormester
04. august 2004 - 14:15 #6
roenving >>
Det er lige nøjagtig sådan noget jeg mangler, men!

"9, aa, ab, ac"

Sådan starter det output jeg får...

det skulle gerne starte med "a, b, c, d [...] x, y, z, 2, 3"
Avatar billede exp Juniormester
04. august 2004 - 14:15 #7
DOOH!!

Blot en lille ændring skulle der til...

<script type="text/javascript">document.write("9, ");lavKoder("9",4000)</script>

===>

<script type="text/javascript">document.write("a, ");lavKoder("a",4000)</script>
Avatar billede roenving Novice
04. august 2004 - 14:20 #8
-- og jeg har lige kigget lidt på den og forberedt den til konvertering til php ...

-- der er stadig en del ting, som skal laves, for adskilige af de funktioner jeg bruger er metoder på objekter, hvor det i php er native funktioner, så det skal lige gennemgås med en tættekam, også variabel-initialiseringen og måske også array-behandlingen skal der sikkert kigges på !-)

function lavKoder($a="a",$n=30){
var $tegn = "abcdefghijkmnpqrstuvwxyz23456789";
var $nyKode = "",$actPlads = new Array(),$newLength = true,$result = new Array();
  for($i=0;$a.length>$i;$i++){
    $actPlads[$i] = $tegn.indexOf($a.charAt($i));
  }
  $tegn = $tegn.split("");
  for($i=0;$n>$i;$i++){
    $actPlads[$a.length-1]++;
    if($actPlads[$a.length-1]==$tegn.length){
      $newLength = true;
      for($j=$a.length-1;$j>=0;$j--){
        if($tegn.length-1>$actPlads[$j]){
          $actPlads[$j]++;
          $newLength = false;
          break;
        }else{
          $actPlads[$j] = 0;
        }
      }
      if($newLength){
        $actPlads[$a.length] = 0;
      }
    }
    $nyKode = "";
    for($j=0;$actPlads.length>$j;$j++){
      $nyKode += $tegn[$actPlads[$j]];
    }
    /*Her skal der laves database-opslag, for at validere $nyKode*/
    $a = $nyKode;
    $result[$result.length] = $nyKode;
  }
  return $result;
}
Avatar billede exp Juniormester
04. august 2004 - 14:27 #9
Der ligger ihvertfald noget arbejde forude...

Det største problem er hvordan jeg kobler det sammen med databasen.
Der skal nemlig ikke genereres en lang række tegnsæt i ét hug, men istedet et af gangen over en længere periode.
Derfor skal den undersøge det i databasen senest indsatte, og generere det nye tegnsæt derud fra.

fx:

13/07 2004 er indsat "abc"
04/08 2004 hentes "abc", og der lægges én til, hvorefter "abd" indsættes i databasen
Avatar billede roenving Novice
04. august 2004 - 14:32 #10
Jeg har jo lavet det som en funktion, der som parametre tager den som ligger lige før og så antallet, så grundlæggende skal den bare lægges ind og kaldes med f.eks.

$kode = lavKoder($gammelKodeFraDatabasen,1);

-- og hvis du altid kun laver en ad gangen, kan du jo helt skippe tælleren og den yderste løkke og den ekstra $result-variabel ...

-- men algoritmen er der i hvert fald !-)
Avatar billede exp Juniormester
04. august 2004 - 14:39 #11
Kigger på det i aften.

Foreløbig tak for hjælpen - nu vil jeg smutte på stranden :-D
Avatar billede exp Juniormester
04. august 2004 - 22:40 #12
roenving >>

Kan ikke få det til at virke :-(

Nogle af disse linier giver ingen mening i mit hoved (jaja... jeg ER en js-spasser):
var $nyKode = "",$actPlads = new Array(),$newLength = true,$result = new Array();
$actPlads[$i] = $tegn.indexOf($a.charAt($i));
$a.length-1
$result[$result.length] = $nyKode;

Kan du overtales til at tilføje nogle flere kommentarer til scriptet?
Avatar billede roenving Novice
04. august 2004 - 22:52 #13
var $nyKode = "",$actPlads = new Array(),$newLength = true,$result = new Array();

er en forkortelse af en initialisering af en række variabler:

nyKode som en tom tekstvar,
actPlads som et array (aktuelt til at holde integers !-)
newLength som boolean true
result som et array (aktuelt til at holde koder (dvs. tekst), som skal returneres !-)


$actPlads[$i] = $tegn.indexOf($a.charAt($i));

er tilsvarende initialiseringen af startværdierne i actPlads-arrayet med at der slås op i reference-strengen og findes ud af, hvor i den streng den enkelte karakter i start-variablen findes ...


.length på en tekst-variabel returnerer strengens længde, den hedder vist length($a) i php ...

.length på et array returnerer antallet af elementer i arrayet, og ved at give en værdi til elementet med det nummer vil man udvide antallet af elementer i arrayet, da det jo er nul-baseret (det har 1 element, når kun array[0] eksisterer !-)

-- håber det bringer dig længere, ellers må du jo spørge ...

-- specielt problemer omkring arrays havde jeg forventet, for jeg ved faktisk ikke hvordan man behandler sådanne i php, mange andre ting havde jeg fornemmelser af !o]
Avatar billede nikolajdu Nybegynder
04. august 2004 - 23:27 #14
exp - jeg spammer lige http://www.eksperten.dk/spm/526104 - Ville egentligt oprette det som tråd på ebruger, men kanikke huske mit password og kan ikke hente det via "glemt password"
Avatar billede roenving Novice
04. august 2004 - 23:33 #15
Vi starter med at have en kode, vi starter fra, f.eks. 'fa8' (1. parameter i kaldet)

Derefter 'oversætter' vi det til et array, som indeholder de pladser, som de indeholdte tegn står på i reference-strengen, her 5,0,30

-- for nemmere at adressere de bogstaver vi skal bygge den enkelte kode af, splitter vi referencen i enkelt-tegn, så den jo så er et array med 32 elementer

Her starter den ydre løkke, som generer det antal koder, der bedes om (2. parameter i kaldet)

Vi markerer lige, at vi måske skal udvide kodens længde, for der laves en ny kode

Først lægger vi en til den sidste plads actPlads-arrayet

Er det så lig med antallet af elementer i reference-strengen/arrayet, skal der ske noget, for det index findes ikke

-- ved første gennemløb findes det problem ikke, så vi hopper direkte udenom

og danner den ny kode ved simpelthen at slå op i reference-strengen/arrayet, med actPlads-værdierne som index og konkatenere dem 5,0,31 --> 'fa9'

Den tilføjes så som et nyt element til relsult-arrayet

-- ved andet gennemløb bliver det tredje element i actArray inkrementeret til 32 og det er netop antallet af elementer i reference-strengen/arrayet, så vi hopper ind i den indre løkke, hvor de øvrige tegn i koden gennemløbes bagfra ...

Hvor første aktion er at sætte det sidste element i actArray til 0 (a skal følge efter 9 !-)

Hvorefter næstsidste element inkrementeres med 1 og faktisk testes på næsten samme måde som sidste element, men da vi ikke skal foretage os yderligere og skal have aflyst udvidelsen af kodelængden, skal vi foretage os noget, selvom vi ikke rammer grænseværdien, så der er byttet om på inkrementeringen og testen, så det er det der forklares i næste afsnit ...

Så først tester vi om vi kan tillade os at inkrementere det næstsidste element, og da vi godt kan tillade os at gøre det, gør vi det, og samtidig aflyser vi udvidelsen af kodelængden, og tilsidst hopper vi ud af løkken, da der ikke er grund til at foretage os noget på det tredjesidste element ...

Så tester vi om der stadig skal udvides, her skal der ikke, så det hopper vi over og konverterer igen til en kode: 5,1,0 --> 'fba' som også føjes til result-arrayet ...

Hvis vi nu havde haft det tilfælde, at vi ikke havde kunnet tillade os at inkrementere nogen af koderne (vi var startet det aktuelle gennemløb med bar 9-taller !-) ville alle de indre tests have resulteret i, at det andet alternativ, næste tegn på en plads er blevet sat til et a, og udvidelsen af koden ville have stået ved magt, og dermed have resulteret i, at actPlads-arrayet var blevet udvidet med et element af værdien nul ...

Ved den efterfølgende konvertering ville vi altså få en kode, som var en længere end den foregående, bestående af bar a'er ...

Når den ydre løkke er gennemløbet det fastsatte antal gange, returnerer vi resultat-arrayet !-)

Simpelt og elefant ...
Avatar billede nicklasb Nybegynder
05. august 2004 - 16:26 #16
så lige dit link fra ebruger.dk, og ser også at du allerede har fået masser af svar. Gider dog hverken at læse koden du har fået igennem (da den er javascript) eller tilhørende tekst, da den efter min mening er en smule lang at skulle læse igennem blot for at ligge et svar!
Så ved ikke om du har fået svar på dit spørgsmål eller ej, så brug min kode hvis du "får lyst"!

Kan stort set ikke se hvad problemet egentligt er. Er det ikke blot bare at gå din kode igennem bagfra og herved analysere hvert enkelt tegn ud fra et array. I tilfælde af at tegnet ligger midt i arrayet tages den næste post, i tilfælde af tegnet er det sidste i arrayet får tegnet status som tegn ét hvorefter næste tegn analyseres?

en hurtig kode uden nogen form for konkrol af hvorvidt tegnene findes i den allerede gennerede kode, kunne se således ud:

<?php
function spec_code($str, $char) {
    $strlenght  = strlen($str) - 1;
    $charlenght = count($char) - 1;
    $action    = true;
    $result    = '';

    while ($strlenght >= 0) {
        if ($action === true) {
            $key = array_search($str{$strlenght}, $char);
            if ($key < $charlenght) {
                $action = false;
                $result = $char[$key + 1] . $result;
            } else {
                $result = 'a' . $result;
            }
        } else {
            $result = $str{$strlenght} . $result;
        }
        $strlenght--;
    }
    if ($action === true) {
        return 'a' . $result;
    } else {
        return $result;
    }
}

$char      = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
echo spec_code('zza', $char);
?>

hvis du også ønsker kontrol af fejl i kode i forhold til char-arrayet kan funktionen in_array ( http://dk.php.net/manual/en/function.in-array.php ) benyttes. Men det må du selv sidde og lege lidt med! :)
Avatar billede exp Juniormester
05. august 2004 - 16:45 #17
niclasb >>
Der er lige nøjagtig det jeg står og mangler :-)

Hvis du lægger et svar, får du dine velfortjente point.


roenving >>
Du smider også lige et svar, så får du lidt for at give mig indblik i, hvordan det kan gøres...
Avatar billede roenving Novice
05. august 2004 - 16:46 #18
Oki '-)
Avatar billede nicklasb Nybegynder
05. august 2004 - 16:50 #19
svar!

kan godt være det virker for nysgerrigt, men hvad i helv... kan man dog bruge sådan et script tid?
Avatar billede exp Juniormester
05. august 2004 - 16:53 #20
nicklasb >>
Det skal jeg vise dig når det er færdigt :-)

Men tro mig - i lige præcis *denne* sammenhæng kan det være en fordel, hvis man er glad for søde brunetter og blondiner ;-)
Avatar billede roenving Novice
05. august 2004 - 16:55 #21
-- tak for point ;~}
Avatar billede exp Juniormester
05. august 2004 - 16:56 #22
P.S.
Hvordan hulan splitter man denne streng op i et array:
$charset = "abcdefghijkmnpqrstuvwxyz";

Håbede sådan, at split("", $charset) eller explode(""), $charset) virkede, men det gør det bare ikke :-(
Avatar billede nicklasb Nybegynder
05. august 2004 - 17:02 #23
uhhh, lyder fint :D

hvis du blot skal hente et enkelt bogstav og du ved hvilken plads du ønsker kan du bare kalde variablen som et array. Altså eksempelvis

echo $charset[3];

er det det du mener?
Avatar billede exp Juniormester
05. august 2004 - 17:08 #24
Nopes - jeg vil gerne have $charset splittet op i at array med et tegn pr. key

egentlig det samme som du gør her:
array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');

bare uden ' og ,
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester