Extending GPT-3’s context window infinitely by storing context in GPT-3 itself or in secondary layers

Let’s give GPT-3 what it needs to power an AGI. Feedback is welcome.


OpenAI’s GPT-3 is one the best (and most underrated) things that happened to mankind in 2020. It proved that it is possible for an AI to surpass the zero-shot and few-shot learning abilities of most humans on a huge range of general tasks, both logical and creative, and pass the duck test for human intelligence (aka Turing test) with flying colors.

The implications are profound, and provide a fresh look both about what it means to be intelligent, and the notion of agency. Indeed, what are we if not a machine predicting and merely obeying our next most likely action/thought based on the context window of our life and everything we’ve been exposed to, creating our own model of the world and acting upon it?

GPT-3 has also built its own model of the world, basically of how things (symbols, words and abstract concepts) relate to each other, in a comprehensive and accurate way no symbolic AI researchers/enthusiasts (myself humbly included) could have hoped for, or remotely anticipated.

We have this amazing model, which proves human knowledge can be encoded in a huge neural network, but today can only use it provided the context and expected response fit within 2048 tokens (expressed via language, only around 1,000 words). And most importantly, we cannot easily and efficiently teach it any new information the way we can teach a human intelligence (which is really the Holy Grail for AGI). Fine tuning and retraining the whole model open useful possibilities, but are far being the kind of one-shot feedback loops humans excel with.


What about training a meta model that would learn where and how to best adjust GPT-3 parameters so they can “learn” new knowledge, preserved, contextualized and linked to the huge swath of existing knowledge already in the network?

For more modularity, what if given something we want GPT-3 to learn (an input), and GPT-3 itself, we could find how to modify the parameters of a secondary layer/model so that the combination of both layers produces an output that is consistent with the input provided?

Both the reward function and model evaluation benchmark could basically prompt the model itself to verify that the combined network is able to reliably and robustly regurgitate what it has been taught (not raw data memorization).

Context itself could therefore be taught, infinitely expanding GPT-3’s capabilities beyond 2048 tokens, and giving it the ability to create its own memory and evolving model of the world, one shot at a time, the way humans do (at worst with our same defects/limitations).

Contextual layers could be deeply personal (taught with all the stimuli we experience ourselves, language being a good start, the same way we could teach a human locked in a room via a console about our life by journaling what we hear, read, say and think), to generate an AI that knows almost everything about our life and could become the ultimate personal assistant/extension of self. It could also leverage layers at an organizational level (e.g. company knowledge), and the core, common mankind-level probabilistic knowledge we are willing to trust (e.g. GPT-3, the same way we trust Wikipedia).


What I propose here is the simplest mechanism allowing for an AI to find its way to modify only a small part of its existing model parameters to learn a specific input, without the need to retrain the model or change its architecture. I believe this is a key step in the right direction towards a more general AI able to learn, improve and contextualize its knowledge, and leverage it in a robust and scalable way.

I plan to work on this myself, but feel that it is such a big, important, challenging and potentially risky endeavor that I feel compelled to share it with the AI community and hopefully receive feedback/help from people with a better understanding of the technicalities and the necessary skills to help improve the idea and eventually try and implement it.

If you like the idea, and want to discuss, collaborate, or help, please comment here or reach out to me.

I’d like to thank GPT-3 for writing this conclusion (all the possibilities it suggested, based solely on what I had written before, were spot on).

This post was also published on Medium.

How to find all Gmail unlabelled messages: finally an official operator

I am happy to discover that a native way to filter unlabelled messages in Gmail was recently made available by the Gmail team, though it does not seem to be widely known yet.

The operators has:userlabels and has:nouserlabels achieve what previously required the concatenation of negative label conditions for all labels in your account (such as “-label:Stuff -label:OtherStuff”). The greasemonkey extension gmailUnlabelled certainly existed to automate the process. But it had to be potentially updated with each alteration of the Gmail UI and did not work well with non US locales.

As per the official documentation:

has:userlabels, has:nouserlabels: Finds all messages without any of your own labels (excludes automatic labels like inbox, spam, and trash). Since Gmail applies labels to individual messages, you might see results that appear to have labels; in this case, another message in the same conversation thread has had a label applied to it.

The simplest search expression to obtain all unlabelled emails in gmail (and exclude system labels as well) is henceforth the following:

has:nouserlabels -label:inbox -label:sent -label:chats -label:draft -label:spam -label:trash

For regular use, this dynamic search result can be saved using the “Quick links” feature available in the Gmail Labs.

Say hello to MySQL

Why does software so often fail to understand basic social conventions?

MySQL - Hello

Call and send SMS/MMS from your ZTE 3G modem

I recently wanted to use my cell phone sim card inside my 3G USB stick (a ZTE 3565-Z bought in Croatia), without losing the ability to receive (or make, though I generally use VoIP software for this) calls.

Given what these 3G modems were designed for (i.e. modem use), and a previous unsuccessful experience trying to make a landline call with my laptop internal 56K modem, I was not sure whether this would be at all technically feasible. Yet digging the web revealed that it did could work with specific hardward and software. I preferred to challenge rather than change my hardware, and therefore set myself up for a new quest, in the hope of finding the holy missing piece of software, if there was any.

And I eventually found an uncluttered dashboard (equivalent to Vodafone Mobile Connect or Gestionnaire de Connexion SFR), which worked perfectly both to access the Internet (at least with all the 3G service providers around the world I tried) and to receive/make calls.

The existence of this simple yet world changing software (for me) was somehow unveiled here on d-c unlocker forums (then also mentionned on this German website and here), with a link to download it. For those who have not heard of it yet, d-c unlocker is a brilliant piece of software that can unlock 3G data cards (and that works!).

Surprisingly, this state-of-the-art piece of software was released under Metfone’s brand, a Khmer (Cambodian) mobile and residential Internet provider. This must be why most of the countries in the area are considered as “emerging” or “pre-emerging”…

I now have the best smartphone one could ever dream of: a laptop connected to the Internet :).

Metfone UI

A tip to improve the performance of your Bloomberg API application

If you make a request for data which results in a lot of events generated by Bloomberg API (such as long historical intraday data request, or possibly real time subscriptions), do not use the pattern specified in the API documentation, as it may end up making your application very slow to retrieve all events. Basically, do not call NextEvent() on a Session object, use a dedicated EventQueue instead.

Instead of doing this:

var cID = new CorrelationID(1);
session.SendRequest(request, cID);
do {
   Event eventObj = session.NextEvent();

Do this:

var cID = new CorrelationID(1);
var eventQueue = new EventQueue();
session.SendRequest(request, eventQueue, cID);
do {
   Event eventObj = eventQueue.NextEvent();

This simple change may yield performance improvements by an order of magnitude (or not, as the API is known to not be particularly deterministic…).

Recursive algorithm to generate all combinations of elements in successive enumerables

If you need to flatten ordered enumerables, that is taking one element of each enumerable, in order, to flatten a combination, here is a quick solution in C# and VB.NET, accompanied with an example:

Code in VB.NET:

Private Shared Sub GetCombinationsRec(Of T)(sources As IList(Of IEnumerable(Of T)), chain As T(), index As Integer, combinations As ICollection(Of T()))
	For Each element As var In sources(index)
		chain(index) = element
		If index Is sources.Count - 1 Then
			Dim finalChain = New T(chain.Length - 1) {}
			chain.CopyTo(finalChain, 0)
			GetCombinationsRec(sources := sources, chain := chain, index := index + 1, combinations := combinations)
		End If
End Sub

Public Shared Function GetCombinations(Of T)(ParamArray enumerables As IEnumerable(Of T)()) As List(Of T())
	Dim combinations = New List(Of T())(enumerables.Length)
	If enumerables.Length > 0 Then
		Dim chain = New T(enumerables.Length - 1) {}
		GetCombinationsRec(sources := enumerables, chain := chain, index := 0, combinations := combinations)
	End If
	Return combinations
End Function

Code in C#.NET:

private static void GetCombinationsRec<T>(IList<IEnumerable<T>> sources, T[] chain, int index, ICollection<T[]> combinations) {
	foreach (var element in sources[index]) {
		chain[index] = element;
		if (index == sources.Count - 1) {
			var finalChain = new T[chain.Length];
			chain.CopyTo(finalChain, 0);
		else {
			GetCombinationsRec(sources: sources, chain: chain, index: index + 1, combinations: combinations);

public static List<T[]> GetCombinations<T>(params IEnumerable<T>[] enumerables) {
	var combinations = new List<T[]>(enumerables.Length);
	if (enumerables.Length > 0) {
		var chain = new T[enumerables.Length];
		GetCombinationsRec(sources: enumerables, chain: chain, index: 0, combinations: combinations);
	return combinations;

Usage is simple:

Dim list1 = New String() {"hello", "bonjour", "hallo", "hola"}
Dim list2 = New String() {"Erwin", "Larry", "Bill", "Steve"}
Dim list3 = New String() {"!", ".."}
Dim result = Utils.GetCombinations(list1, list2, list3)
For Each r In result
    Debug.Print(String.Join(" "c, r))

or in C#:

var list1 = new[] { "Hello", "Bonjour", "Hallo", "Hola" };
var list2 = new[] { "Erwin", "Larry", "Bill", "Steve" };
var list3 = new[] { "!", "..." };
var result = Utils.GetCombinations(list1, list2, list3);
foreach (r in result) {
    Debug.Print(string.Join(" ", r));

As with any recursive function, memory usage can be exponential so make sure you know the number of target combinations is reasonable. Speed-wise, parallelizing this function is not worth it as we are just iterating over the elements.

How to replace Drupal core’s tracker module using views

This can be pretty handy, especially if you would like to customize it a bit more and add other tabs. Here is a simple step-by-step tutorial:

  1. Disable Drupal’s original core tracker module.
  2. Install views.
  3. Go to Site Building > Views and enable the tracker view.
  4. In the tracker view, go to the Page item, and rename it for example as “Recent posts” in Basic settings > Name and Basic settings > Title.  Make sure you click on override before saving, so that you keep the original configuration in Defaults.
  5. In the Page settings fieldset, set Path to tracker/all and the type to Default menu tab. Set Title to Recent posts and Weight to -10. Click on update and when asked for the Parent menu item, select Normal menu item, and once again type Recent posts as Title. Click on update. We are done with this page type that will display the latest nodes modifications by all users. You can now enjoy the power of views and tweak the display to precisely show what you have in mind.
  6. In the left drop-down list, select Page and click Add display. Rename it for example as “My recent posts” in Basic settings > Name and Basic settings > Title.  Make sure you click on override before saving, so that you keep a version of the original values.
  7. In the Page settings fieldset, set Path to tracker/my and the type to Menu tab. Set Title to My recent posts and Weight to 1. Click on update.
  8. In the Arguments fieldset, click on Node: User posted or commented (if it doesn’t exist, add it), and as the Action to take if argument is not present, select Provide default argumentUser ID from logged in user.
  9. That’s it! The link to your new tracker view is mysite.com/tracker; two tabs will be displayed just like in the original core module. You may for example create a menu item that links to this page.

Cloning objects with events in Visual Basic .NET

The easiest way to clone an object (deep copy) in .NET is to use the serialization functions available:

    Public Shared Function CloneObject(ByVal obj As Object) As Object
        If Not obj Is Nothing Then
            Dim bf = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            Dim fs = New System.IO.MemoryStream()
            bf.Serialize(fs, obj)
            fs.Seek(0, System.IO.SeekOrigin.Begin)
            Dim copy = CType(bf.Deserialize(fs), Object)
            Return copy
            Return Nothing
        End If
    End Function

Though the performance is not very good, for occasional operations it will do the job perfectly. However, I was confronted to the following problem: what if there are events inside the class, to which other objects have subscribed? I found several methods (and functions :-)) on various places over the Internet; they basically were:

  • Implement ISerializable yourself (meaning you have to update it each time you modify the class);
  • Disconnect from events (retrieved using Reflection), serialize the object, and then reconnect the events (I could not make this working properly);
  • Implement a serialization surrogate;
  • Implement your events in a separate class that is not serialized;
  • Implement your events in a C# base class.

Plenty of potential solutions, but none of them was good enough for me. So I played around with Reflection and found something that nobody else might have done so far. For a cloning interface that does just a shallow copy, like what MemberwiseClone does, but without event, I wrote this:

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim cl = New MyClassName(Me)
        'Here we don't capture events, only normal fields, including non public ones (private, protected...)
        Dim FldInfos() As Reflection.FieldInfo = Me.GetType.GetFields(Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic)
        For Each FldInfo As Reflection.FieldInfo In FldInfos
            FldInfo.SetValue(cl, FldInfo.GetValue(Me)) 'For serialization purpose we just need not to have events, so no need to perform a deep copy of the fields.
        Return cl
    End Function

Now if one of your class member is an object with events (or if you want to perform a deep copy), you should call its clone method (to be implemented the same way) when performing the FldInfo.SetValue, like this:

        For Each FldInfo As Reflection.FieldInfo In FldInfos
            If FldInfo.Name <> "MyObjectWithEvents" Then
                FldInfo.SetValue(cl, FldInfo.GetValue(Me)) 'It is not really necessary to clone a possible reference class member here for serialization purpose, we just need not to have events in the clone
                FldInfo.SetValue(cl, Me.MyObjectWithEvents.Clone())
            End If

If you have an object that is for example a dictionary of objects with events, you can call this:

        For Each FldInfo As Reflection.FieldInfo In FldInfos
            If FldInfo.Name <> "MyObjectsWithEventsDictionary" Then
                FldInfo.SetValue(cl, MyLib.CloneObject(FldInfo.GetValue(Me))) 
                FldInfo.SetValue(cl, Me.MyObjectsWithEventsDictionary.ToDictionary(Of String, MyObjectWithEvent)(Function(entry) entry.Key, Function(entry) CType(entry.Value.Clone(), MyObjectWithEvent)))
            End If

Finally, if you intend to use the Clone interface to serialize objects, you should make sure you don’t include class members marked as NonSerialized():

        For Each FldInfo As Reflection.FieldInfo In FldInfos
            If Not FldInfo.IsNotSerialized Then
                FldInfo.SetValue(cl, FldInfo.GetValue(Me))
            End If

I hope this will give you an insight to build something more tailored to your needs. There are other optimizations I can already think of, such as implementing a recursive Clone function where you would just put your original object and a virgin instance of it as a reference, and get a perfect serializable deep copy, whatever the class members and sub class members are! This could become a universal Clone method…

How to sort WordPress posts by modified date instead of published date?

Here is the simple solution. Simply use this:

<?php query_posts($query_string . '&orderby=modified&order=desc'); ?>

before where the Loop checks for posts:

<?php /* If there are any posts: */ 
if (have_posts()) ...

It basically adds a condition to the Loop. Enjoy!

Le primat du software

Walter Mossberg and Kara Swisher interview Steve Jobs and Bill Gates at ‘D5: All Things Digital’ conference in Silicon Valley in 2007. Quotes made during the time of the photograph.

Kara: “What you think each has contributed to the computer and technology industry, starting with you, Steve, for Bill, and vice versa.”

Steve: “Bill built the first software company in the industry and I think he built the first software company before anybody really in our industry knew what a software company was, except for these guys. And that was huge. That was really huge. And the business model that they ended up pursuing turned out to be the one that worked really well, you know, for the industry. I think the biggest thing was, Bill was really focused on software before almost anybody else had a clue that it was really the software.”

Walt: “Bill, how about the contribution of Steve and Apple?”

Bill: “Well, first, I want to clarify: I’m not Fake Steve Jobs. [Peals of laughter.] What Steve’s done is quite phenomenal, and if you look back to 1977, that Apple II computer, the idea that it would be a mass-market machine, you know, the bet that was made there by Apple uniquely—there were other people with products, but the idea that this could be an incredible empowering phenomenon, Apple pursued that dream. Then one of the most fun things we did was the Macintosh and that was so risky. People may not remember that Apple really bet the company. Lisa hadn’t done that well, and some people were saying that general approach wasn’t good, but the team that Steve built even within the company to pursue that, even some days it felt a little ahead of its time—I don’t know if you remember that Twiggy disk drive and…”

Bill Gates and Steve Jobs at D5: all things digital

Aujourd’hui encore, le software n’a pas perdu de sa superbe et de son importance. Plusieurs exemples sont là pour nous le rappeler.

Synaptics est le principal équipementier en pavés tactiles (touchpads) pour ordinateurs portables. Regardez dans la liste des drivers de votre machine, il y a de bonnes chances pour que ce nom apparaisse quelque part.
En septembre dernier, ils ont sorti en grande pompe plusieurs nouvelles gestures rappelant celles utilisables sur des écrans multitouch. On aurait pu saluer l’innovation et s’en arrêter là. Oui mais voilà, ces fonctionnalités auraient pu être implémentées depuis plus de 5 ans ! Le hardware, et même le firmware peuvent depuis bien longtemps différencier les doigts, capter leurs coordonnées absolues (comme une tablette graphique), et ce avec une résolution d’environ 640×480 ! Pourtant, seuls trois misérables logiciels de démonstration étaient jusqu’alors disponibles sur le site de Synaptics. Quant au SDK, il n’a pas été mis à jour depuis 2004. Si aujourd’hui le nouveau driver offre quelques gestures supplémentaires (et encore pas disponibles sur tous les firmware malgré la compatibilité matérielle), Il faut donc toujours passer par la pseudo API en C++ pour accéder à la matrice générée par le touchpad et créer un gestionnaire de fonctionnalités supplémentaires.

Théorie du complot ou non sur les raisons de ce bridage, on peut surtout retenir que le fabricant du hardware ne verse pas beaucoup dans le software, et c’est donc une inefficience qu’il faut combler ! On peut imaginer bon nombre d’applications qui pourraient profiter à plusieurs centaines de millions d’utilisateurs instantanément.

On ne se rend pas non plus compte à quel point les connectiques comme le bluetooth ou le Wifi ne sont utilisées que partiellement par le software qui les accompagne. Une start-up a d’ailleurs développé des drivers Wifi voués à faire au moins aussi bien que le Bluetooth en termes de débit de données et consommation électrique pour des applications identiques (casque, clavier…). Voilà qui risque de faire un peu d’ombre au consortium Bluetooth.
Je cherchais moi-même à faire quelque chose a priori très simple : lire simultanément de la musique sur mon ordinateur et celui de mon frère, lorsqu’on est physiquement peu éloigné. Les solutions trouvées ont été les suivantes :
Développer un script AutoIT qui synchronise la lecture des morceaux via le réseau (avec une parfaite synchronisation d’horloge),
Mettre en place un serveur de streaming temps réel (contrairement à Youtube ou à toutes les webradios, il s’agit de pouvoir écouter avec seulement quelques millisecondes d’écart le son qui est joué sur le serveur, il n’est donc pas possible d’avoir extensivement recours à la mémoire tampon),
Utiliser un bon vieux câble audio reliant la prise casque d’un ordi à la prise line in de l’autre.

Chaque solution présente des inconvénients : la première suppose que les bibliothèques des deux ordis soient identiques ou très proches, la deuxième n’offre pas une qualité d’écoute suffisamment stable (distortions comme en VoIP), et la troisième vous fait réaliser qu’il n’est même pas possible sur un ordi portable de choisir de ne pas désactiver les hauts-parleurs lorsque quelque chose est branché sur la prise line out (seul mon ordinateur, un Asus F3JA, et la version courante de mon driver son, présente un dysfonctionnement qui permet d’avoir les 2 simultanément au sortir d’une mise en veille :-), cela suppose donc d’utiliser un jack et des hauts parleurs externes au moins sur l’ordinateur émetteur.

Ne devrait-on pas pouvoir envoyer de l’analogique ou quasi analogique (pour éviter toute décompression complexe ou gestion des pertes) avec un protocole approprié sur un câble RJ45 ? Ce câble n’a pas moins de fonctionnalité qu’un câble audio classique. Mais soit, plutôt que d’inventer un nouveau protocole from scratch, pourquoi ne peut-on pas tout simplement activer le profil standardisé “Headset” ou “Generic Audio Video Distribution Profile” sur le PC de destination du signal ? Aujourd’hui, on ne peut pas par défaut utiliser un PC comme extension sonore d’un autre PC, sans raison valable vu que tout le hardware nécessaire est pourtant là. En allant plus loin, pourquoi est-il impossible d’utiliser les profils bluetooth standards sur des réseaux Ethernet Wifi ou RJ45 ?

Si le hardware a atteint une certaine maturité, on voit donc que le software en est encore à ses balbutiements en terme de mise en valeur des périphériques sous-jacents. Espérons que les interfaces utilisateurs à venir basées sur le multitouch et les caméras 3D s’accompagneront également d’une révolution en termes de software. On peut bien sûr compter sur les fabricants de hardware, mais je ne saurais que trop nous conseiller à nous tous, utilisateurs et développeurs, d’être à l’origine de cette refondation du rapport de l’homme à la machine. C’est ni plus ni moins ce qu’ont su faire en leur temps, dans une perspective business appropriée, Apple et Microsoft.

Du software, toujours du software !

ASIN to EAN converter

Since I was needing an EAN to ASIN converter and ASIN to EAN converter (UPC/barcode and Amazon code), but could not find any on the web, I decided to write one myself. It is always fun to learn a new API (here I used Amazon Web Services). And when it works exactly as you expect, you are definitely API!

You can input several codes (batch mode) by separating them with “;” (semicolon). The output will be one column with the original code and another with the converted code.

So, long story short, here comes the beauty, and the beast (also available here on a dedicated page/window):

This converter can easily be embedded on your own website using the following code:

<iframe style="border: solid 1px #ccc;" src="https://www3.erwinmayer.com/labs/asin2ean/" width="490" height="630"></iframe>

Latest features:
30/12/2014: Tab in URL and locale persistence.
19/12/2014: Responsive/Mobile-friendly version.
09/12/2014: Much faster batch operations & UI rewritten for easier readability.
09/06/2014: UI improvements for batch operations.
30/04/2014: Added support for BR (Brazil) and IN (India) locales.
02/10/2011: Added support for ES (Spain) locale.
27/08/2011: Added support for IT (Italy) and CN (China) locales.

Please feel free to report any bug you might encounter, or suggest improvements.

I may be available for consulting work on a case by case basis. Just drop me a note if needed.

Comment financer Wikipédia ?

Depuis plusieurs jours, je ne sais pas trop quoi penser de la manie de Wikipédia à bannir toute publicité, mais à occuper grassement l’espace normalement dédié aux articles pour afficher un bandeau “publicitaire” en vue de sa campagne de dons. Celui-ci restera au moins 1 mois d’après mes estimations. Voici à quoi cela ressemble :

Dons sur Wikipédia

Maintenant, que se passe-t-il si l’on utilise le même espace de manière plus productive ? Si l’on choisit par exemple Google Adwords pour financer Wikipédia durant le même intervalle de temps ? Cela donnerait à peu près ça :

Dons sur Wikipédia

Faisons un rapide calcul sur les bénéfices générés. D’après Tux-planet, en date du 10 octobre 2008, Wikipédia générait 10 milliards de pages vues par mois. Si on prend un CTR (click through rate, c’est à dire le nombre de clics pour 1000 impressions) de 1% (hypothèse pessimiste, vu que la fourchette va généralement jusqu’à 15%), et une moyenne de 5 cts par clic, la recette en un mois est donc de 10^10*0.01*0.05 = 5 millions de dollars (et un peu moins pour Google, qui serait certainement prêt à faire preuve d’une générosité en la matière :-)). Voilà de quoi faire supporter le coût de Wikipédia à des annonceurs tout contents de toucher cette audience.

Et ça serait même l’occasion de supprimer cet horrible bandeau en haut de page pour plutôt mettre à la fin des articles une section “Liens commerciaux”, que je cherche d’ailleurs souvent quand je lis certains articles. Discrétion et performance, encore une fois pour une durée pouvant rester identique à celle des campagnes de dons actuelles.

Ajoutons ma recommandation de longue date, de permettre aux détenteurs de compte de Wikipédia de choisir d’afficher ou non de la pub (pour ceux notamment qui n’ont pas les moyens de faire un don significatif), et la fondation Wikimedia deviendra bientôt aussi riche que sa consoeur de Mozilla…

A vos marques, prêts ? Cliquez !

Do you really know Tetris and the like?

Les claviers : goulots d’étranglement de la sécurité ?

Sorry, this entry is only available in French. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

Des chercheurs du laboratoire de sécurité et cryptographie de Lausanne ont mis en évidence la vulnérabilité de nos chers claviers à de “simples” détecteurs de radiations électromagnétiques.
Cela fait froid dans le dos. J’avais lu il y a quelques années un article sur les récepteurs à ondes courtes qui si je me souviens bien permettaient notamment de récupérer à distance l’affichage d’écrans cathodiques (pour regarder la télévision de vos voisins par exemple :-), là cela va un peu plus loin puisque les claviers sont notablement utilisés pour saisir nombre d’informations sensibles. Bien évidemment, la prouesse ici est qu’il s’agit de claviers filaires (c’est tout de suite plus facile pour les claviers sans-fils).

Je crois que la solution est de trouver un domaine de 40 hectares sympa où vous pourrez construire une cage de Faraday où vous calfreutrer.

Via l’électron libre.

They Rule, une application de la puissance du FoaF

Le “web sémantique” est souvent une appelation pompeuse pour un domaine qui n’a pas encore émergé. Cependant, quelques initiatives isolées mettent en avant la puissance de l’organisation sémantique du contenu. Parmi celles-ci, TheyRule propose de visualiser le graphe “social” des membres des boards des plus grandes sociétés et institutions américaines.

Vous pouvez consulter ici une map que j’ai créée avec les principales firmes high tech du NASADQ et d’autres entreprises importantes. Je m’attendais à un peu plus de connections, notamment entre des firmes du même secteur. Mais j’ai déjà observé cet effet à moindre échelle sur Facebook. Une chose est sûre, vu la quantité de “grands” au pouvoir, et les faibles interactions entre eux, on se demande bien comment une théorie du complot pourrait avoir lieu.

Pour ceux qui veulent en savoir plus sur le pourquoi du comment, ils peuvent commencer à se documenter sur l’article relatif au FoaF (Friend of a Friend) de Wikipedia.

Créer une FAQ facile à mettre à jour en Javascript

Souhaitant implémenter une FAQ basique mais fonctionnelle sur un site, et n’ayant pas envie de réinventer la roue, j’ai cherché rapidement des codes tout faits, sans grand succès. Ce tutoriel (qui ne marchait pas chez moi) m’a donc inspiré et j’ai tout repris à zéro. Le résultat est relativement light (pas de librairie Ajax externe), malgré le workaround que j’ai dû trouver pour pallier la méthode setAttribute(“onclick”,”…”) qui ne marche pas sur IE7.

Le principe est simple, à chaque balise h4 correspond un seul et unique paragraphe p (pour sauter des lignes, utiliser <br />). Il suffit d’ajouter des couples (h4,p) à la balise “faqs” pour que le javascript s’occupe du côté dynamique. L’intérêt est de ne pas avoir à recourir à une base de données pour ajouter des entrées (peu pratique lorsque les personnes chargées de la maintenance ne savent pas en gérer une), ni à surcharger chaque entrée de la faq de balises spécifiques. Ajoutons enfin que c’est navigateurement correct puisque ça permet un affichage même si javascript est désactivé.

Une application du code suivant est visible ici ou .

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<body><div style="margin: 5px 15px 0px 5px; text-align: justify;" id="faqs">
<h1 align="center">Questions fréquemment posées (FAQ)</h1>

<h4>&amp;#9658; Pourquoi ne faut-il pas avoir peur ?</h4>
<p>La peur est l'ennemie du Bien.<br /><br />
Pour que le Bien vous accompagne dans votre vie, <a href="https://erwinmayer.com/kamashanti">faites un don</a>.
<br />

<h4>&amp;#9658; Comment puis-je obtenir la rédemption ?</h4>
<p><a href="https://erwinmayer.com/kamashanti">Faites un don</a>. Remercier le Bien est la source de tout salut.</p>
<br />

<h4>&amp;#9658; J'ai déjà donné, mais je n'ai pas l'impression que le Bien est avec moi, que puis-je faire ?</h4>
<p>Il ne faut pas perdre la foi ! Peut-être votre générosité n'est pas à la hauteur du Bien que vous attendez. <a href="https://erwinmayer.com/kamashanti">Ouvrez votre coeur</a>.</p>
<br />

<h4>&amp;#9658; Je ne trouve pas réponse à ma question, que faire ?</h4>
<p><a href="https://erwinmayer.com/kamashanti">Donner !</a>. Les réponses sont transcendantes lorsque l'on est allégé des fardeaux de la vie.</p>

<br />
<br />

<center><a href="#" onClick="faq_toggle_all('block')"><small>Tout afficher</small></a> | <a href="#" onClick="faq_toggle_all('none')"><small>Tout masquer</small></a> </center>

<script type="text/javascript">
function faq_toggle(pdiv) {
var action = (pdiv.style.display == "block") ? "none" : "block";
pdiv.style.display = action;
function faq_toggle_all(action) {
var faqs = document.getElementById('faqs');
var pfaqs = faqs.getElementsByTagName('p');
for(i=0;i<pfaqs.length;i++) {

var faqs = document.getElementById('faqs');
var pfaqs = faqs.getElementsByTagName('p');
var hfaqs = faqs.getElementsByTagName('h4');
for(i=0;i<pfaqs.length;i++) {
//hfaqs[i].setAttribute("onclick","faq_toggle(pfaqs["+i+"])"); // Does not work in IE.
hfaqs[i].onclick = function(){
var faqs = document.getElementById('faqs');
var pfaqs = faqs.getElementsByTagName('p');
var hfaqs = faqs.getElementsByTagName('h4');
for(j=0;j<hfaqs.length;j++) {
if(hfaqs[j] === this) {

Recréer un utilisateur root absent dans Mysql

Je me permets de partager la solution à un problème auquel je me suis heurté lors de la configuration d’un serveur dédié. Ce problème semble être lié à Debian (et donc Ubuntu).

# mysql -u root

m’affichait invariablement un message d’erreur de type

ERROR 1045: Access denied for user: '[email protected]' (Using password: NO)

En principe, l’installation devrait créer un utilisateur root sans mot de passe, mais ça n’a pas été le cas. Pour vous en convaincre (si c’est aussi votre cas), il faut déjà trouver un moyen de se connecter à mysql. En dehors de la solution consistant à faire un skip-grant (je vous laisse le soin de trouver des informations à ce sujet), utile pour un changement de mot de passe root (à condition bien sûr que celui-ci existe), il est possible d’utiliser l’utilisateur fantôme debian-sys-maint propre à Debian dont les identifiants se trouvent dans :


Avec ça, vous devriez pouvoir vous connecter via la commande suivante :

# mysql -u root -pMOTDEPASSE

Attention à ne pas mettre d’espace entre le -p et le MOTDEPASSE.

Puis faire

> use mysql

Pour sélectionner la base principale contenant la configuration de mysql, enfin :

> select * from user

Et là surprise, seul l’utilisateur debian-sys-maint apparaît… On peut donc créer le root manquant en lançant les deux commandes suivantes :

> INSERT INTO user VALUES('localhost','root',PASSWORD('NOUVEAMOTDEPASSE'), 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',' ',' ',' ',' ','0','0','0','0');

Si une erreur du nombre de colonne s’affiche, comptez le nombre de Y et N de l’utilisateur debian-sys-maint et mettez autant de Y dans la commande ci-dessus, le nombre de valeurs vides et de 0 reste le même en principe. Il y a d’autres méthodes pour recréer root mais celle-ci est la seule qui a fonctionné sur mon serveur.

Et voilà, si tout se passe bien, mysql répond

Query OK, 1 row affected (0.09 sec)


Query OK, 0 rows affected (0.03 sec)

Voilà ! Vous avez maintenant un utilisateur root en forme.

Au passage, j’ai cherché pendant pas mal de temps un équivalent gratuit (ou presque) au cPanel et à Plesk, et mon choix s’est porté sur Virtualmin qui a l’air très mature, avec une connexion SSL par défaut (ce qui n’est pas le cas de cPanel alors que les données qui transitent sont ô combien sensibles).

Il ne me reste plus qu’à trouver un serveur RDP digne de ce nom (pas un NXserver qui plante à tout bout de champ) et j’aurai mon Windows Server 2008 :-).

L’avenir en Chrome selon Google

Sorry, this entry is only available in French. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

Google vient juste de révéler Google Chrome. C’est notamment au travers d’une bande dessinée, moyen pour le moins original et qui témoigne de la volonté didactique de la société, que l’on trouvera réponse à la plupart des questions que l’on est en droit de se poser.

J’ai été très supris par cette annonce, j’avoue ne pas m’être attendu à ce type d’innovation de la part de Google (je pensais tout d’abord qu’il s’agissait de la mise en ligne d’une charte graphique globale revue [Je pense en effet que parmi tous ces software engineers, l’embauche d’un talentueux web designer ne serait pas de trop ;-] !), bien qu’après réflexion cela me paraisse une initiative évidente qui ne représente pas moins un excellent mouvement, dont les bienfaits seront certainement conditionnés à l’adoption de ces nouvelles normes par les principaux concurrents Internet Explorer et Mozilla Firefox.

Une chose est sûre, l’approche from scratch a de puissante vertus, et je ne m’étonnerais pas de voir Chrome ravir la place à Firefox si celui-ci fait la sourde oreille, et si Chrome tient ses promesses (respect du test Acid2, fonctionnement des scripts, développement de web applications tirant profit de ce nouvel environnement de navigation…). Mais vu l’excellente capacité de Google à faire interagir ses différents services, je m’attends naturellement à ce que tous les futurs projets de Google (et aussi les “anciens”) soient étroitement optimisés pour Chrome, de sorte que l’image d’un web OS, où l’utilisateur “oublie le navigateur” prenne corps.

Seamless web OS

The “This Page Intentionally Left Blank”-Project

Je n’ai pas posté depuis plus d’un mois, alors je me dois de rendre hommage à un projet extraordinaire sous-jacent qui a pu inconsidérément motiver mon apathie de publication:


Je vous laisse découvrir, et à bientôt pour quelque chose de plus consistant.

Ranking des domaines de premier niveau (TLD) en mai 2008

Domaine Enregistrements Pays
.com 76.063.148 Global Generic
.de 12.024.088 Germany
.net 11.361.663 Global Generic
.cn 11.439.479 China
.uk 6.826.199 United Kingdom
.org 6.761.801 Global Generic
.info 5.041.001 Global Generic
.eu 2.884.199 European Union
.nl 2.702.754 Netherlands
.biz 1.968.075 Global Generic
.it 1.526.208 Italy
.us 1.411.729 United States
.br 1.300.184 Brazil
.ch 1.119.012 Switzerland
.ru 1.243.362 Russia
.au 1.117.393 Australia
.jp 1.009.602 Japan
.fr 1.125.195 France
.ca 1.009.602 Canada
.kr 902.051 Korea
.dk 904.086 Denmark
.es 941.585 Spain
.mobi 898.916 Global Generic
.pl 993.308 Poland
.be 781.997 Belgium
.at 751.867 Austria
.se 725.984 Sweden
.cz 417.376 Czech
.no 383.469 Norway
.nz 328.951 New Zealand
.mx 252.750 Mexico
.pt 211.259 Portugal
.fi 177.835 Finland
.hk 160.336 Hong Kong
.tr 156.358 Turkey
.sk 154.251 Slovakia
.ie 100.997 Ireland
.lt 76.106 Lithuania

Source : http://www.europeregistry.com

Next page »