Laden...

Forenbeiträge von Traumzauberbaum Ingesamt 512 Beiträge

02.04.2007 - 17:59 Uhr

An sich ist das keine Redundanz, sondern nur unterschiedliche Zugriffspfade. Einmal hat man den Zugriffspfad über die Spielfelder, oder man hat den Zugriffspfad über den Spieler, aber es ist ja immer die selbe Spielfigur.

Also eine Art Index. Natürlich kann das Sinn machen, es hängt davon ab wie gut die einzelnen Zugriffspfade auf deine Anwendung passen. Es ist zum Beispiel eigentlich immer Sinnvoll einen Zugriffspfad über das Spielfeld zu haben. Man will ja ziemlich oft auf Kollisionen testen. Manchmal will man aber auch für alle Figuren eines Spielers eine bestimmte Aktion ausführen (sie sollen blinken z.B.), dann ist der Zugriffspfad über den Spieler natürlich der bessere.

Redundant wird es eigentlich erst dann, wenn man z.B. im Spielfeld speichert, wo die Spielfigur ist, und in der Spielfigur speichert, auf welchem Feld sie sich befindet. Oder zu welchem Spieler gehört die Figur, und welche Figuren gehören dem Spieler. Dann hat man die Informationen doppelt vorliegen, und muss dann dafür sorgen, dass die Daten konsistent bleiben. Das ist an sich aber auch unkritisch. Problematisch kann es dann werden, wenn mehrere Threads gleichzeitig auf den Daten arbeiten.

30.03.2007 - 20:19 Uhr

Du könntest auch einfach die Dienste auf manuell stellen und eben nur starten, wenn du sie brauchst. Z.B. als "External Tools" das Starten aller benötigten Dienste ablegen.
Mein Notebook ist um Welten schlechter als deines, reicht aber locker als Entwicklungsumgebung mit VS 2005 Professional und SQL Express 2005 und teilweise auch noch Oracle Express, was alleine schon meinen ganzen RAM frisst. Klar braucht er manchmal etwas, aber das liegt im Sekundenbereich und ist wirklich zu verkraften. Also daran liegts schonmal nicht, oder deine Ansprüche sind zu hoch 😉

25.03.2007 - 01:25 Uhr

Ein Weblog hat mich auf den Gedanken gebracht. Was haltet ihr für die größten Sünden die so in der Programmierwelt verbreitet sind?

Ich leg mal zum besseren Verständniss ein paar Beispiele vor:

Premature Optimization

Heute hab ich doch tatsächlich in einem msdn Forum die Frage gelesen:
Was ist effizienter StringBuilder.AppendLine() oder StringBuilder.Append( Environment.NewLine ) ?
Aber das ist ja eigentlich noch ein harmloses Beispiel. Schlimm wird es dann, wenn man ganze Verwaltungsstrukturen aufbaut und vermeindlich optimiert, und dann am Ende der Flaschenhals ganz woanders sitzt.
Viele schlaue Leute haben es schon gesagt: Bring das Programm erstmal zum Laufen und lokalisiere dann die Problemstellen. Oder auch "Premature optimization is the root of all evil"
Natürlich sollte man schon ein Auge drauf haben, welcher Lösungsweg für die Situation der Beste ist. Nachträgliche Änderungen können auch viel Zeit kosten. Aber man darf sich nicht in Mikrooptimierung verlieren ("Diese Multiplikation kann ich auch mit Shift&Add umsetzen") und im Zweifel zwischen Optimierung und Aufwand (und man sollte oft zweifeln) den einfacheren Weg wählen.

Feature Overkill

Man hat gerade eine Klasse implementiert und denkt sich, dass die Klasse eigentlich auch noch ein paar andere Dinge machen könnte. Wenn man dann zurück blickt, stellt man fest, dass man nur seine Zeit damit verschwendet hat. Hier erweist sich das YAGNI Prinzip als hilfreich: You Aren't Gonna Need It. Ist eigentlich ein Prinzip aus eXtreme Programming, aber imo ein recht allgemein anwendbares. Erstmal alle Anforderungen erfüllen, sich nicht selbst neue Anforderungen (und damit Arbeit) schaffen. Das hält auch den Code kürzer, und weniger Code ist leichter wartbar.

Reinventing the Wheel

Damit fängt glaub ich jeder an. Aber das Problem ist ja nicht ein Anfänger, der mal selbst eine Linked List programmiert oder eine Vektorklasse implementiert. Eigentlich ist das auch ein Punkt, der mich weniger bei anderen stört, als bei mir selbst. Ich finde es einfach dann schade um die Zeit, wenn man etwas baut, und dann feststellt, dass es im Framework schon enthalten ist, wenn auch etwas abgewandelt. Oder dass es schon eine (oft freie) Bibliothek dafür gibt.
Umso schlimmer wenn man das mit Absicht macht, weil man anderen zu wenig zutraut, oder keine Lust (manche nennen das auch Inkompetenz) hat rauszufinden, wie man diese fremde Bibliothek benutzen soll.

Was haltet ihr für die häufigsten (tödlichen) Fehler in der Programmierung? Was nervt euch an Code und Programmen von anderen oder von euch selbst am meisten? Wobei der Schwerpunkt auf Fehlern trotz Wissen liegen sollte 😉 also nicht aus Unerfahrenheit oder Anfängerfehler 🙂 Vieleicht kann man ja noch etwas lernen.

24.03.2007 - 16:55 Uhr

Ich hab nichts gegen Singletons. Ich hab nur was dagegen, dass auf sie zurückgegriffen wird, obwohl man sie nicht braucht. Ich kann nichtmal was von einer Argumentation von dir erkennen. Du sagst nur, dass static das gleiche wäre, was nunmal nicht stimmt.
Wohlgemerkt hab ich nie davon gesprochen den Login zu einer statischen Klasse zu machen, aber irgendwie hab ich den Eindruck, dass du es genau so verstehen willst.

Der Unterschied:

  • Singletons gehören niemanden. Jeder hat darauf gleiche Zugriffsrechte.
    Eine statische Variable gehört zu einer Klasse. Diese Klasse hat volle Zugriffsrechte und räumt anderen die Rechte dafür ein.

  • Singletons erzwingen, dass nur eine Instanz erstellt werden kann. In nahezu allen Fällen braucht man das nicht. Das ist aber der Entscheidende Punkt eines Singletons. Warum ein Singleton benutzen und sich damit Einschränkungen auferlegen, die nicht nötig sind.
    Eine normale Klasse erzwingt erstmal garnichts. Dass man diese Klasse auch für statische Variablen benutzt, kann der Klasse ja ziemlich egal sein, außer es würde eben zu Fehlern führen.

  • Wie siehts denn bei Singletons mit Vererbung aus? Da wirds schon etwas komplizierter, so dass man im Normallfall erstmal auch das ausschließt (private Konstruktor, nicht protected). Das meinte ich damit, dass du auch keine Klasse sealed machst, nur weil du Vererbung nicht brauchst.

Wenn du das nicht hier in dem Thread klären willst, kannst du mir auch gerne eine PM schreiben. Aber bis jetzt erkenne ich von dir leider garkeinen Punkt der mich irgendwie weiter bringen würde. Du sagst nur, dass es eigentlich das gleiche ist. Ich erkenne nichtmal im Ansatz, wo sich das auch nur ähnlich sein sollte, eine statische Variable anzulegen, oder ein Singleton Pattern zu benutzen.
Mit dem einen benutzt man eine Klasse, mit dem anderen definiert man eine Klasse.

Es gibt noch viele weitere Patterns die für diese Aufgabe genauso falsch wären wie Singleton: Singlestate oder Dependency Injection. Die erledigen die einzige gestellte Anforderung von globaler Zugreifbarkeit genauso und haben wie das Singleton Nebenwirkungen, die einen nicht weiter stören würden. Ich sehe nichts was bei einer ganz simplen Anforderung von globaler Sichtbarkeit für eines davon sprechen würde.
Warum nicht einfach eine statische Variable hinterlegen, die von einem definierten Punkt aus setzen und von überall Verwendung erlauben? Warum eines dieser Patterns verwenden, und sich damit Einschränkungen ins Haus holen, die man nicht braucht?

Wenn kein Grund für Singleton spricht, würde ich es wie gesagt einfach nach dem KISS Prinzip als statische Variable anlegen, oder überlegen es nicht doch als Parameter weiterzureichen.

24.03.2007 - 11:51 Uhr

Original von herbivore
Hallo Traumzauberbaum,

es kann immer nur ein Benutzer zur Zeit angemeldet sein. Deshalb Singleton. Ganz im Sinne des Pattern. 🙂 Demzufolge laufen deine Einwände alle ins Leere.

Man abgesehen davon, dass ich static hier nicht nur für ungünstig halte, sondern die Konsequenz von static ebenfalls wäre, dass es die Daten nur einmal gäbe. Denn static hat genau so viel oder wenig mit global zu tun wie Singleton. static bedeutet genauso wie Singleton, dass es die Daten nur einmal gibt. Wenn also deine Argumentation greifen würde (was sie m.E. nicht tut, s.o.), dass es hier um Globalität und nicht um Einzigartigkeit ging, wäre static genauso unpassend wie Singleton. Wenn deine Argumentation also greifen würde, liefe dein Vorschlag also darauf hinaus, den Teufel mit dem Beelzebub auszutreiben. 🙂

herbivore

Nein eben nicht. Es gibt dann so viele Instanzen von der Klasse, wie man Variablen anlegt. Ob diese static sind, ist doch egal. Man baut es nicht in die Definition der Klasse ein, wie sie benutzt wird. Beim Singleton darf es genau nur eines geben und du legst fest, wie sie benutzt werden soll, und das ohne einen Grund dafür zu haben. Und du weißt genau wer dann diese static Variablen setzt, beim Singleton weiß man das nicht.

Und genau dein erster Abschnitt ist, was mich so gewaltig an dem Singleton stört: Es kann nur ein Benutzer angemeldet sein, es muss aber nicht. Es führt nicht zu Fehlern wenn mehrere Instanzen dieser Klasse existieren würden, also warum nur eine einzige erzwingen?
Machst du Klassen sealed, weil du sie in diesem Programm nicht ableiten willst?

Man legt nicht etwas fest, was man nicht wirklich auch braucht. Die Einzigartigkeit braucht man in den seltensten Fällen, warum also das Singleton benutzen? Das ist nur für Einzigartigkeit da, wird aber in 99% der Fälle benutzt, weil man nicht weiß, wo man die static Variable sonst hinlegen soll.

24.03.2007 - 10:50 Uhr

Und Singleton halte ich in den meisten Fällen für absolut falsch und unnötig. Es ist eben ein einfaches Pattern, und dadurch auch das Bekannteste.

Z.B. zwingt dich Singleton dazu, dass es nur eine Instanz gibt. In den meisten Fällen wo Singleton eingesetzt und auch von herbivore vorgeschlagen wird, ist einem das egal, weil man eh nur eine Instanz braucht, und man nimmt es eben als Nebeneffekt in kauf. Nahezu nie wird es eingesetzt, weil um Fehler bei mehrfacher Instanzierung zu Vermeiden (z.B. wenn man 2 mal auf die Grafik zugreift führt das garantiert zu Fehlern).

Aber das ist der Punkt: Man will eigentlich globalen Zugriff, nimmt aber ein Pattern, dass als Hauptmerkmal eigentlich nur das Erzwingen von nur einer Instanz hat. Das ist einfach ein Misbrauch dieses Patterns in Anwendungsfällen, die dieses Pattern nicht brauchen. Und ich verstehe nicht warum herbivore es in jedem Thread zum Thema globale Variablen vorschlägt.

Bevor man ein Pattern verwendet, sollte man sich Fragen, ob man denn das wünscht, was das Pattern realisiert. Das Singleton-Pattern realisiert das verhindern von mehreren Instanzen. Braucht man das in diesem Fall? Ich denke eher nicht.
Wenn es nur um Sichtbarkeit geht, sollte man eine stinknormale statische Variable benutzen. Dort hat man dann nämlich den Vorteil, dass man die Sichtbarkeit und Setzbarkeit eindeutig regeln kann. Bei einem Singleton erstellt der die Instanz, der zuerst kommt. Welche Klasse führt den Login durch? Die, die zuerst kommt. Finde ich äußerst fragwürdig.

23.03.2007 - 19:53 Uhr

Ich würde eher sagen, es funktioniert nicht in Konstruktoren. Erst nach dem Konstruktor kann für das Control der DesignMode eingeschaltet werden, weil Site zu dem Zeitpunkt noch nicht gesetzt ist.

Ich hab zu dem Thema zwei Lösungsideen gefunden:

  1. Den Code aus dem Konstruktor nach Init verschieben
  2. LicenseManager.UsageMode == LicenseUsageMode.Designtime abfragen

Wobei die Erste eigentlich die Schönere ist.

Ansonsten mal nach DesignMode und Constructor googeln.

22.03.2007 - 13:42 Uhr

Gut, ich wollte mir auch nicht zu viel Gedanken machen.
Hab eben grob die zwei Prinzipien eingebaut: Selektion und Kombination

Da mir für die Selektion auf die schnelle nichts cleveres eingefallen ist, hab ich einfach über das quadrat der Zufallszahl eine simple Verteilung genommen, die eher die "guten" Werte nimmt, aber auch mal bei den schlechten zuschlagen kann.
In die Reproduktion hab ich dann noch Mutation eingebaut (das bei default), um Pech bei der Initialisierung etwas zu kompensieren.

In den meisten Fällen klappts, manchmal kommt aber auch nichts gutes raus. War ja zu erwarten. Aber ich bin froh, dass es so weit wenigstens etwas funktioniert 😉

22.03.2007 - 13:03 Uhr

Was ist denn an dem Pattern schlecht?
Dann kann ich aus dem Index der Gruppe auf den gematchten Inhalt schließen 😉

Hab mich eben an nem genetischen Algorithmus versucht:


private static Random rand = new Random();

private static double Fitness( int guess, string text )
{
	string guessText = guess.ToString( "d10" );

	if( guessText.Length > text.Length )
		text = new string( '0', guessText.Length - text.Length ) + text;
	
	int matches = 0;
	for( int i = 0; i < text.Length; ++i )
	{
		if( guessText[i] == text[i] )
		{
			++matches;
		}
	}

	double fitness = (double)matches / (double)text.Length;

	return fitness;
}

private static int Reproduce( int a, int b )
{
	int bigger = Math.Max( a, b );
	int smaller = Math.Min( a, b );

	int result = 0;

	while( bigger != 0 )
	{
		result *= 10;

		switch( rand.Next( 0, 5 ) )
		{
			case 0:
			case 1:
				result += bigger%10;
				break;

			case 2:
			case 3:
				result += smaller%10;
				break;

			default:
				result += rand.Next( 0, 10 );
				break;
		}

		bigger /= 10;
		smaller /= 10;
	}
	return result;
}

public static int Str2Int( string text )
{
	int[] generation = new int[4096];
	double[] fitness = new double[generation.Length];

	for( int i = 0; i < generation.Length; ++i )
	{
		generation[i] = rand.Next( -1, int.MaxValue ) + 1;
		fitness[i] = Fitness( generation[i], text );
	}

	List<int> newGeneration = new List<int>( generation.Length );
	double h;
	int a, b;

	for( int i = 0; i < 1000; ++i )
	{
		Array.Sort( fitness, generation );
		if( fitness[generation.Length - 1] == 1.0 )
			return generation[generation.Length - 1];

		for( int k = 1; k < generation.Length / 4; ++k )
			newGeneration.Add( generation[generation.Length-k] );
		
		while( newGeneration.Count < generation.Length )
		{
			h = rand.NextDouble();
			h *= h;
			h = Math.Round( h * (generation.Length - 1) ) + 1.0;
			a = generation[generation.Length - (int)h];

			h = rand.NextDouble();
			h *= h;
			h = Math.Round( h * (generation.Length - 1) ) + 1.0;
			b = generation[generation.Length - (int)h];

			newGeneration.Add( Reproduce( a, b ) );
		}

		generation = newGeneration.ToArray();
		newGeneration.Clear();
		for( int k = 0; k < generation.Length; ++k )
			fitness[k] = Fitness( generation[k], text );
	}

	return generation[generation.Length - 1];
}

Ich hab nicht wirklich Ahnung davon. Wäre also nett wenn jemand kommentieren könnte, ob das überhaupt etwas GA ähnliches ist 😉

Erstaunlicherweise funktioniert das sogar recht gut. Für positive Zahlen wohlgemerkt.

EDIT: Noch einen Fehler behoben, jetzt überleben die Besten 😉

21.03.2007 - 21:26 Uhr

Original von Moooitic
Arg, lol,

Ich rede die ganze zeit über ref -_- (daher auch immer der pointer vergleich - out ist ja etwas anders)

Damit hab ich schon fast gerechnet, aber dazu möchte ich auch noch was sagen:

Eine dumme Verwendung von Schlüsselworten ist kein Argument gegen die Schlüsselworte, sondern gegen diese Art von Verwendung.

Pointer selbst sind sehr gut mit OOP vereinbar. Man kann einen Pointer genauso als Klasse verstehen, wie ein Array. C++ unterscheidet ja nichtmal zwischen den beiden, und in C# könnte man jedes ref auch durch ein Array ersetzen. Aber ist das dann OOP, nur weil ich das gleiche ohne ref mache?

Sobald du ein normalen Referenztypen übergibst, musst du doch auch damit rechnen, dass die Funktion dieses Objekt verändern kann. Wo ist der Unterschied zu einem Pointer?

21.03.2007 - 21:00 Uhr

Original von Moooitic
Nein das stimmt nicht.
Der "Aufrufer" bestimmt im out fall nicht was geändert wird sondern nur was "möglich" ist geändert zu werden - und das ist auch genau die kritik.

Nein das stimmt nicht, ein out Parameter MUSS genauso wie ein return gesetzt werden, bevor die Methode verlassen wird.

Innerhalb einer Methode, die mit out Parametern definiert wurde, besteht absolut kein Unterschied zwischen return und out.

Außerhalb der Methode ist in C# der Unterschied, dass man das Return nicht in einer Variable festhalten MUSS. Wohlgemerkt aber in C#, Iron Python z.B. behandelt die Returns und outs völlig gleich.

Du darfst dich nicht an dem TryParse festhalten, du kritisierst schließlich out im Allgemeinen. Es gibt aber Algorithmen, die haben einfach mehrere Rückgabewerte, z.B. div und mod. Hinter den beiden steht exakt der gleiche Algorithmus, also würde man doppelten Code schreiben, wenn man out verwendet. Das hat schon was von Fanatismus im Namen von OOP gegen eines der Grundideen von OOP zu verstoßen.
Oder man führt ein Objekttyp ein, der Tupel beschreibt. Oder man Verwendet Arrays. Nur was ist der Vorteil? Der Nachteil ist, dass man bei einem Tupel und Array an der Signatur der Funktion erstmal nicht weiß, wieviele Werte zurückgegeben werden, und welche Bedeutung diese haben.

21.03.2007 - 19:33 Uhr

Warum ist es denn für OOP natürlich maximal einen Rückgabewert zu haben?

Ein out Parameter ist doch äquivalent zu dem, was man über return zurückgibt.

21.03.2007 - 18:28 Uhr

Ach verdammt, hier noch die gewünschte Variante mit Regex:


public static int Str2Int( string text )
{
	const string pattern = @"(0)|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(.)";

	int result = 0;
	int sign = 1;
	if( text.StartsWith( "-" ) )
	{
		text = text.Substring( 1 );
		sign = -1;
	}

	checked
	{
		MatchEvaluator eval = delegate( Match m )
		{
			for( int i = 1; i <= 10; ++i )
			{
				if( m.Groups[i].Success )
				{
					result *= 10;
					result += (i-1)*sign;
					return "";
				}
			}
			throw new FormatException();
		};
	
		Regex.Replace( text, pattern, eval );
	}

	return result;
}

21.03.2007 - 17:33 Uhr

Naja Regex hilft schonmal ein paar auszusieben, die nicht konvertiert werden können. Und man kann damit auch negative Zahlen erkennen.

Einen Kurzen hab ich noch, dann reichts aber für heute:


public static int Str2Int( string text )
{
	using( DataTable t = new DataTable() )
	{
		return (int)t.Compute( text, null );
	}
}

21.03.2007 - 16:37 Uhr

Binäre Suche:


public static int Str2Int( string text )
{
	int sign = text.StartsWith( "-" ) ? -1 : 1;

	text = text.TrimStart( '-', '0' );

	double max = Math.Pow( 10, text.Length ) - 1.0;

	uint upperBound = max > int.MaxValue ? (uint)int.MaxValue + 1 : (uint)max;
	uint lowerBound = (uint)Math.Pow( 10, text.Length - 1 );

	uint pivot;
	int compare;

	checked
	{
		while( lowerBound <= upperBound )
		{
			pivot = (upperBound>>1) + (lowerBound>>1) + (1&upperBound&lowerBound);
			compare = pivot.ToString().CompareTo( text );
			if( compare < 0 )
			{
				lowerBound = pivot + 1;
			}
			else if( compare > 0 )
			{
				upperBound = pivot - 1;
			}
			else
			{
				unchecked
				{
					return (int)pivot < 0 ? (int)pivot : (int)pivot * sign;
				}
			}
		}
	}

	throw new FormatException();
}

Und hier noch die CodeDom Variante von dr4g0n76 Ansatz:


private static void Eval()
{
	string text = (string)AppDomain.CurrentDomain.GetData( "text" );
	CodeTypeDeclaration typeDecl = new CodeTypeDeclaration();
	typeDecl.Name = "Eval";

	CodeMemberMethod methodDecl = new CodeMemberMethod();
	methodDecl.Name = "GetHashCode";
	methodDecl.Attributes = MemberAttributes.Public|MemberAttributes.Override;
	methodDecl.Statements.Add( new CodeMethodReturnStatement( new CodeSnippetExpression( text ) ) );
	methodDecl.ReturnType = new CodeTypeReference( typeof( int ) );

	typeDecl.Members.Add( methodDecl );

	CodeNamespace ns = new CodeNamespace( "Generated" );
	ns.Types.Add( typeDecl );

	CodeCompileUnit unit = new CodeCompileUnit();
	unit.Namespaces.Add( ns );

	CompilerParameters parameters = new CompilerParameters();
	parameters.GenerateInMemory = true;
	parameters.GenerateExecutable = false;

	Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
	CompilerResults result = provider.CompileAssemblyFromDom( parameters, unit );

	if( result.Errors.HasErrors )
	{
		string s = "";
		foreach( CompilerError error in result.Errors )
			s += error.ErrorText;
		throw new FormatException();
	}

	Type t = result.CompiledAssembly.GetType( "Generated.Eval" );
	
	AppDomain.CurrentDomain.SetData( "value", Activator.CreateInstance( t ).GetHashCode() );
}

public static int Str2Int( string text )
{
	AppDomain evalDomain = AppDomain.CreateDomain( "EvalDomain" );

	evalDomain.SetData( "text", text );

	evalDomain.DoCallBack( Eval );

	int result = (int)evalDomain.GetData( "value" );

	AppDomain.Unload( evalDomain );

	return result;
}

@TEry

Wenn du eine ernsthafte Lösung willst, dann wär der Thread in 2 Zeilen zuende:

int.Parse
RTFM

Ich denke auch wenn das Ziel hier eher trivial gibt, kann man doch viel aus den Lösungswegen lernen.

21.03.2007 - 14:24 Uhr
public static int Str2Int( string text, params char[] digits )
{
    int digitValue;
    int result = 0;
    int b = digits.Length;

    Dictionary<char,int> digitMap = new Dictionary<char,int>( digits.Length );

    for( int i = 0; i < digits.Length; ++i )
    {
        digitMap[digits[i]] = i;
    }

    for( int i = 0; i < text.Length; ++i )
    {
        if( !digitMap.TryGetValue( text[i], out digitValue ) )
            throw new FormatException();

        result = result*b + digitValue;
    }
    return result;
}

Aufruf z.B:

Binär:
Str2Int( "10110", '0', '1' )

Dezimal:
Str2Int( "1234", '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' )

😁

Da fällt mir gerade noch eine ein, mit der ich Borgs Lösung im Worst-Case noch schlage:

public static int Str2Int( string text )
{
    Random rand = new Random();
    int result = 0;
    while( result.ToString() != text )
    {
        result = rand.Next( int.MinValue, int.MaxValue );
    }
    return result;
}
21.03.2007 - 12:04 Uhr

Ich weiß nicht warum ihr in ein IST mehr legt, als es bedeutet. IST bedeutet nicht ist optimal. Ich wollte damit doch nur die aktuelle Lage beschreiben, den IST-Zustand, und keine Prognose für die Zukunft abgeben.

Um Faktorisierung zu lösen ist der Aufwand im Allgemeinen (also ohne weitere Eigenschaften der Zahl voraussetzen zu können) exponentiell. Das ist doch einfach so, auch wenn es in Zukunft anders werden könnte.

Ich hab doch sogar geschrieben, dass PKE erst genau dann nicht mehr sicher ist, wenn ein polynomieller Algorithmus gefunden wird. Und dort steht nicht in einem Anhängsel "aber das wird nicht passieren" oder sowas.

Aber wenn man sich die ersten zwei Zeilen rauspickt...

Vieleicht ist das unglücklich formuliert, aber das deswegen als Quatsch zu bezeichnen und noch so nen Prolog dazu zu schreiben... ich glaube da darf ich mich angegriffen fühlen.

20.03.2007 - 18:27 Uhr

Die Idee ist sehr interessant und ich halte es sogar für möglich, dass man mit dieser völlig anderen Architektur eines "Rechners" auch völlig neue Algorithmen findet, die in der Laufzeit viel besser sind, oder sogar die erwähnte Polynomialzeit haben.

Ich finde es nur unglaubwürdig, dass wenn man einen guten Algorithmus für Faktorisierung findet (den man ja wie gesagt haben muss für PKE), dass man sich dann an Public Key Verfahren aufhängt 😉
Wenn man publiziert, dass man einen solchen Algorithmus gefunden hat, und das dann verifiziert wird, geht man in die Analen der Mathematik ein und wird berühmt wie Einstein. Da sind die Public Key Verfahren doch eher ein Sandkorn in der Wüste.

20.03.2007 - 18:09 Uhr

Sorry aber irgendwie bin ich immer recht angefressen, wenn jemand glaubt die Weisheit mit dem Löffel gefressen zu haben.

Ja ich weiß, dass es einen Faktorisierungsalgorithmus in Polynomialzeit für Quantencomputer gibt. Aber das kann mit diesem Threadtitel wohl kaum gemeint sein oder?

Ansonsten IST Faktorisierung exponentiell im Aufwand. Es gibt keinen Algorithmus der für beliebige Zahlen in der Eingabelänge polynomial ist. Weiß garnicht was du mir da vorwerfen musst. Der Aufwand für Faktorisierung, und damit für das Knacken von Public Key Verfahren, daran ist garnichts Quatsch.
Es ist nicht bewiesen, dass es so sein muss, das hab ich auch nicht behauptet. Aber im Moment ist es einfach so, weil keine besseren Verfahren bekannt sind.

Exponentiell heißt nicht, dass es keine guten Verfahren für bestimmte Eingaben gibt. Aber es gibt keine guten Verfahren für ALLE Eingaben. Es spielt nunmal keine Rolle, ob es einen Algorithmus gibt, der Zahlen mit 1000 Stellen knacken kann. Weil der Aufwand exponentiell ist, brauch ich nur 2000 Stellen draus machen, und der Algorithmus versagt wieder völlig.

Im Gegensatz zur Faktorisierung ist das Erstellen eines Schlüssels beliebiger größe relativ leicht. Man nimmt sich einfach zwei beliebig große Zahlen, die wahrscheinlich Primzahlen sind. Die Wahrscheinlichkeit lässt sich mit Leichtigkeit auf sehr kleine Werte bringen, und für die Verfahren ist es auch nicht wichtig, ob diese zwei Zahlen wirklich Primzahlen sind.

Und durch diesen Unterschied zwischen Erstellung von beliebigen Schlüsseln und knacken von beliebigen Schlüsseln leben die Public Key Verfahren. Das heißt solange Faktorisierung ein exponentielles Problem ist, so lange sind Public Key Verfahren sicher. Egal ob es jetzt einen guten Algorithmus gelingt eine Zahl mit x Stellen schnell zu faktorisieren. In diesem Wettrüsten sind die Schlüsselgeneratoren immer weit voraus, außer jemand findet einen polynomialen Algorithmus.

Komplexität von Faktorisierung

20.03.2007 - 16:22 Uhr

Kannst auch struct draus machen, dann gibts kein null 😉

20.03.2007 - 16:17 Uhr

Mein Vorschlag wäre: IronPython

Das kann man leicht in C# Code einbauen, und kann mit Zahlen beliebiger Größe rechnen.

20.03.2007 - 15:19 Uhr

Original von dr4g0n76
Vielleicht ist es ja einfach nur Quatsch?! Ich bin mir da auch nicht sicher, nicht einfach alles zu glauben ist ja ok. Ohne Skepsis läuft man auf jeden Fall öfter mal auf.

Aber:

  • seht euch mal an was Combots probiert...
  • augmented reality, hätte ich vor ein paar Jahren noch nicht für möglich gehalten
  • KI Chatbots
  • Blue Pill

Und das sind keine leeren Versprechungen, sondern diese Projekte existieren real, wenn man das auch teilweise vielleicht nicht glauben mag.

Es tut sich auf jeden Fall was. In allen Bereichen.

Das ist das schöne an der Mathematik. Was bewiesen ist, bleibt auch so, da tut sich nichts.

Und es ist bewiesen, dass Public Key Knacken genauso schwer ist wie Primzahlfaktorisierung. Das heißt, dass der Aufwand exponentiell ist. Das heißt, wenn das tolle Programm nur 2,3 Sekunden zum Knacken braucht, hängt man eben noch 2 Bytes ran und es braucht wieder 1 Jahr.

Wie schnell man einen Public Key knacken kann, ist völlig uninteressant. Es ist leicht das wieder zu ändern. Gescheitert ist es erst dann, wenn Faktorisierung in polynomialzeit möglich ist.

Ansonsten sollte jedem hoffentlich klar sein, dass Public Key Verfahren nicht 100% sicher sind, nie waren, und garnicht sein können. Stichwort Man in the Middle, ihr könnt Public Key nur vertrauen, wenn ihr allen Routern zwischen eurem PC und dem Ziel PC auch vertraut.

20.03.2007 - 13:18 Uhr

Hab Ähnliches auch schon beobachtet. Aber ich hab den Eindruck, das Timeout wird dann weggelassen, wenn die Netzwerkverbindung gerade aufgebaut wird.

Aber ich hab noch nicht festgestellt, dass das irgendwo Probleme verursacht. Das Fehlschlagen der Verbindung muss man einplanen, da spielt es doch dann auch keine Rolle mehr, wie schnell er fehlschlägt.

19.03.2007 - 19:28 Uhr

Es gibt ein paar Klassen, die direkt auf Threading in Windows.Forms ausgelegt sind.
Eine davon ist der BackgroundWorker.

19.03.2007 - 17:11 Uhr

Original von Golo
Ohne das jetzt getestet zu haben, halte ich alle drei für falsch.

1: Dass es "" in C# gibt, wäre mir neu.
2: Das @ ist zu viel, da gerade dadurch die \ NICHT geparsedwerden.
3: Das ist nicht das, was er haben wollte (' statt ")

Variante 2 ohne @ ist IMHO korrekt.

  1. "" gibt es, aber nur wenn man ein @ vor den String setzt.

Man vertausche als den String von 2 mit dem von 1 und alle drei Varianten funktionieren.

19.03.2007 - 14:57 Uhr

Die Diskussion ist schon lange sinnlos, weil nicht klar definiert ist, was gesucht ist.

Fängt ja schon damit an: Was ist ein Unterschied?

19.03.2007 - 13:25 Uhr

Original von nin
karte ? fürs Konzert ? wenn ja, wo und wann??

Diese Woche in Berlin, aber für Karten ist es definitiv zu spät.
Auf Ebay könntest eventuell was bekommen.

Ich bin wie gesagt durch den Quake Soundtrack zu NIN gekommen.

19.03.2007 - 11:46 Uhr

Tja das zeigt ziemlich deutlich, dass das Problem zu schwammig beschrieben ist. Mal ganz davon abgesehen, dass das vom Schwierigkeitsgrad her auch eine Hausaufgabe sein könnte.

19.03.2007 - 10:15 Uhr

SingleCall wird ja bei jedem Methodenaufruf neu erstellt.
Singleton bleibt eine Weile erhalten und bedient alle Anfragen.

SingleCall ist also nur für einen Aufruf und damit auch nur für eine Verbindung zuständig.
Singleton bedient mehrere Verbindungen gleichzeitig.

In einem SingleCall kannst du also keine Daten speichern, die für einen späteren Aufruf gebraucht werden.
Dafür musst du dich beim Singleton eventuell darum kümmern, dass die Daten von verschiedenen Verbindungen getrennt gespeichert werden. Und du musst dich eventuell um Synchronisation kümmern.

18.03.2007 - 14:39 Uhr

Das geht ja schon rein theoretisch kaum.

Stell dir vor du hast ein Programm, dass alle 1 ms drankommen soll. Das Programm muss soll alle 1 ms nen Takt geben, d.h. es muss auch innerhalb der 1 ms komplett fertig werden. Die benötigte Rechenzeit für einen Takt sei t. Lass das Programm dann (1 ms/t) + 1 mal starten, und es ist unmöglich, das alle innerhalb von 1 ms einen Takt geben.

17.03.2007 - 22:09 Uhr

Original von CaptainIglo
Hi,

nein das ist nicht mein Fehler. Ich erstellte mit VS in den Settings eine Vareable vom Typ string und name "Test" und versuchte diesen als erstes auszulesen mit folgendem Code:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationLevel.None);  
KeyValueConfigurationElement element = config.AppSettings.Settings["Test"];  
MessageBox.Show(element.Value);  

Und da bekam ich schon eine Exception das element.Value null sei...

Wahrscheinlich meinst du, dass element null ist. Das passiert, wenn es keinen Eintrag mit Key "Test" gibt. Oder z.B. keine Konfigurationsdatei mit dem Exenamen + .config im Verzeichnis liegt.
Ansonsten funktioniert das wunderbar. Wenn das element nicht null ist, kannst du Value setzen und die config Speichern. Wenn es null ist, rufst du Add auf und fügst Key und Value hinzu.
Musst auch die Section nicht removen. Bei mir hat es zumindest ohne funktioniert.

17.03.2007 - 22:02 Uhr

Naja ne gewissen Anfälligkeit ist auf nem Multi Tasking Betriebssystem nicht auszuschalten. Wenns blöd läuft und der PC entsprechend ausgelastet ist.

17.03.2007 - 14:38 Uhr

Du kannst die ApplicationSettings auch verändern. Du musst nur vorher das Configuration Objekt über ConfigurationManager.OpenExeConfiguration holen, und dort dann auf die AppSettings zugreifen, statt über ConfigurationManager.AppSettings zu gehen.

16.03.2007 - 19:58 Uhr

Steht mit weit oben auf der Playlist 😁

Seit Quake ungefähr.

16.03.2007 - 10:47 Uhr

Ich würde mal die völlig unbasierte Vermutung in den Raum stellen, dass es was mit Invoke zu tun hat.

Du könntest mal BeginInvoke versuchen.

16.03.2007 - 10:21 Uhr

Das musst du alles selbst implementieren. Ist ja aber nicht weiter schwer.

Du solltest dir aber unbedingt überlegen, wie genau du das Ergebnis wissen willst. Schon die Fakultät von 21 bringt Int64 zum Überlauf.
Da hilft entweder Double zu verwenden, wodurch du leichte Ungenauigkeiten verkraften musst, oder du suchst dir eine BigInteger Bibliothek für beliebig große ganze Zahlen (wie z.B. bei IronPython mitgeliefert).

Und du solltest so wenig wie möglich Fakultäten benutzen. Siehe die Definition von Wikipedia:

Wenn du double benutzt, wirst du wohl mit der Formel nach dem 1. = am günstigsten Fahren. Wenn du BigInteger benutzt, solltest du die Formel nach dem 2. = benutzen (da sonst gerundet wird).

Und beachte:

Wähle die Variante, wo der untere Teil kleiner ist.

15.03.2007 - 18:13 Uhr

Vista wäre mir im Moment noch zu gewagt. Für nen Heimrechner zum Spielen vieleicht, aber fürs echte Arbeiten wär mir das zu experimentell.

Ein Core2 Duo ist aber eine sehr gute Wahl. Sowohl für Notebook, als auch für Virtualisierung.

Den L2 Cache kann man schwer einschätzen. Natürlich bringt es was, aber wenn wir von Office reden, macht es wirklich nicht den Unterschied zwischen bedienbar und zu-langsam aus.

15.03.2007 - 18:00 Uhr

Prüf mal nach, ob die Exception vieleicht von einer anderen Exception geschachtelt wird. D.h. auf unterster Ebene die Exception abfangen und selbst ausgeben.
Mehr fällt mir dazu auch nicht ein.

Erstellst du den Thread genauso wie im Beispiel? Viele Optionen hat man ja nicht...

15.03.2007 - 16:06 Uhr

Es gibt eine Methode im ConigurationManager mit der man die Konfiguration über einen Pfad auswählt. Das sollte für deine Zwecke völlig genügen. Du musst die Konfiguration nur irgendwo zentral ablegen, so dass beide Anwendungen den Pfad kennen und zugreifen können.

15.03.2007 - 13:21 Uhr

Danke, die Antwort hilft mir schon weiter. Auf die Idee wär ich garnicht gekommen.
Gefunden hab ich jetzt das hier:

Link

Das hilft mir erstmal weiter, ich werd überlegen welcher der genannten Varianten für mich am günstigsten wäre.

15.03.2007 - 12:12 Uhr

Was ist denn der Unterschied zwischen dieser DLL und z.B. IronPython oder NUnit, wo das problemlos auch mit VS klappt?

Der Unterschied für mich war, dass ich die Rhino.Mocks selbst in den GAC installieren musste. Vieleicht hab ich da was falsch gemacht. Mein Aufruf war einfach:

gacutil /i "Rhino.Mocks.dll"
15.03.2007 - 11:51 Uhr

Ich benutze für UnitTests Rhino Mocks. Da ich das in vielen Projekten mache, und diese Projekte auch alle in SVN liegen, will ich diese DLL in den GAC installieren.

Das an sich funktioniert auch so weit. Die Assembly ist im GAC und wird auch von dort geladen, wenn sie referenziert wird. Auch in SharpDevelop kann ich ohne Probleme diese Referenz aus dem GAC hinzufügen.

Nur in Visual Studio bekomme ich diese Datei nicht angezeigt. Wenn ich es per Hand in das Projekt eintrage, macht es keine Probleme. Aber ich krieg Visual Studio einfach nicht dazu, diese DLL auch aufzulisten, wenn ich "Add Reference" ausführen will.

Wie gesagt funktioniert das gleiche in SharpDevelop ohne ein Problem.

Hat jemand eine Idee woran das liegen könnte, und wie ich das beheben kann? Es ist nicht sehr dramatisch, aber doch nervig, wenn ich jedes mal die Projektdatei per Hand editieren muss.

15.03.2007 - 11:31 Uhr

String sind nicht veränderbar. Alle Funktionen auf Strings (und DateTime) ändern nicht das Objekt selbst, sondern liefern ein neues Objekt mit diesen Änderungen zurück.

D.h. du musst .TrimEnd( " " ) einer Variable zuweisen, und dort steht dann der neue Text drin.

15.03.2007 - 09:01 Uhr

Den GUI Thread über Abort abzubrechen ist auch eine schlechte Idee. Sieht mir so aus, als ob du genau das versuchst.

Eine ThreadAbortException kann man nicht auffangen, sondern nur behandeln. Die ThreadAbortException wird automatisch sofort nach dem finally wieder gesetzt.
Dafür ists auch eine der wenigen Exceptions, die normalerweise nicht das Programm beenden, wenn sie nicht gefangen werden.

13.03.2007 - 19:15 Uhr

Der Satz ist trotzdem sehr denkwürdig 🙂

Hier noch mein Beitrag zu Thema:

Home of the Underdogs

Dort gibt es nahezu alles an Spielen, was legal zu erhalten ist.

JoeQuake

Quake unter Windows zum Laufen bringen. Die Spieldaten braucht man aber noch extra dazu.

13.03.2007 - 16:52 Uhr

Invoke verlagert die Aktivität in den GUI Thread. Der GUI Thread wird also so lange blockiert, wie diese Aktivität dauert. Also nur kurze Aktivitäten über Invoke aufrufen.

Und Controls können problemlos im gleichen Thread manipuliert werden, wo sie erstellt werden. Wenn du sie also nirgends zuordnest, sondern nur so freischwebend für z.B. Formatierung in RichText benutzt, brauchst du Invoke nicht.

12.03.2007 - 22:24 Uhr

Weiß nicht was genau die Anforderungen an die Unterschrift sind.
Mit einer einfachen PictureBox kannst du z.B. die Maus-Events abfangen und Linien zwischen die Punkte malen. Ich hab das mal für Präsentationszwecke gemacht, und das Ergebnis sah eigentlich ganz gut aus.
Du meinst doch das Compact Framework oder?

12.03.2007 - 22:14 Uhr

Ich würde eigentlich von ner eigenen Scriptsprache völlig abraten. Es gibt heutzutage sehr gute Scriptsprachen, die man leicht in bestehendes Programm einbinden kann.

Ich seh nicht so recht, was man dadurch gewinnt, wenn man eine eigene Scriptsprache benutzt. Außer man interessiert sich mehr für den Vorgang des Compilerbaus, als das Ergebnis an sich.

Prinzipiell würde ich als erstes mal zur Scriptsprache IronPython raten. Die ist wirklich sehr gut und flott, und lässt sich sehr leicht in ein Programm einbinden.
Trifft nur nicht ganz deine Wünsche, Python ist sehr Formatorientiert, also Befehle werden immer auf eine Zeile geschrieben, strukturierte Programmierung (if, for, ...) muss durch Einrücken gekennzeichnet werden.

Das nächste wäre vieleicht, dass du direkt C# als Sprache benutzt, und die Codedateien eben nur zur Laufzeit übersetzt. Das geht auch relativ einfach, wird nur auch leicht komplizierter, wenn man z.B. andere Referenzen als den Standard braucht.
Hier ein Beispiel

Aber ich würde mir wirklich gründlich überlegen, was für Vorteile ich mir davon erhoffe, eine ganz eigene Scriptsprache zu bauen. Und die Vorteile müssen schon ziemlich überwältigend sein um den Aufwand aufzuwiegen.

12.03.2007 - 17:34 Uhr

Beim Ersten bekommst du Probleme bei null.
Das Zweite ist zu Visual Basic 😉
Das Dritte ist eigentlich überflüssig, wenn du weißt, dass es ein String ist.

Performance mäßig wird das alles keinen Unterschied machen.

12.03.2007 - 00:33 Uhr

Ich würde auch sagen ein Archiv (wie zip) und dazu eine XML mit den zusätzlichen Daten. In dem XML kannst dann den Dateien auch noch zusätzliche Informationen zuordnen. Base64 wird wirklich verflucht groß.