Arxiu de la categoria: Informàtica i comunicacions

Notes sobre programació, sistemes operatius, comunicacions

Servei DNS4EU

DNS4EU és un servei de resolució de noms (DNS) cofinançat per la Unió Europea, amb diversos nivells de protecció (sense filtres, evitar webs malicioses, evitar contingut inadequat per a criatures, evitar anuncis).

La configuració estàndard està pensada i és gratuïta per a ús particular, si bé ofereixen opcions per a empreses i organitzacions governamentals.

Durant molts anys he fet servir OpenDNS, i aquesta setmana he canviat a DNS4EU.

Un inconvenient: només admeten DOH amb http/2; el router que tinc fa servir http/1.1 per DOH. Tinc esperances que aviat això canviï.

Amb OpenDNS feia servir DOH, tot i que al log del router cada dia s’hi registraven alguns errors.

HTTP/3

HTTP/3 activat per aquest blog.

Costa moltíssim avançar estàndards en la tecnologia de fons d’internet. IPv6 no s’implanta, encara hi ha moltíssim HTTP/1.1, i només el frau i la privacitat ha forçat l’extensió de la navegació encriptada (https).

12/01/26: He hagut de tocar el fitxer de configuració nginx per fer servir $host on hi havia $http_host.

Em queda algun error a les eines d’administració de wordpress, també relacionat amb HTTP_HOST; confio que el resoldré retocant una mica més la configuració de nginx.

14/01/2026: Resumeixo els passos:

Cal permetre el tràfic amb protocol UDP pel port en què hi ha el web (normalment 443).

Nginx ha d’estar compilat amb l’opció –with-http_v3_module.

Al bloc server de nginx.conf cal afegir:

    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;
    http3 on;
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers on;

    add_header alt-svc 'h3=":443"; ma=86400';

    reuseport només es pot fer servir a un dels servidors.

    No tinc clar que ssl_prefer_server_ciphers sigui estrictament necessari.

    add_header alt-svc publicita la disponibilitat de HTTP/3 per aquest servidor.

    I wordpress necessita $HTTP_HOST informat, l’he passat a l’entorn fastcgi de php-fpm a partir de $HOST:

    fastcgi_param HTTP_HOST $host;

    Python: eliminació espais superflus

    Python no té una funció específica per eliminar espais superflus (és a dir, eliminar tots els espais del principi i del final d’un text, i entre paraules deixar-hi només un espai).

    Hi ha una manera molt pythònica de fer-ho:

    " ".join(text_amb_espais.split())

    I això és ràpid? Doncs comparem 3 alternatives amb timeit:

    • Aquesta de join i split
    • Un bucle pas a pas: mirar caràcter a caràcter si hauríem de posar-lo al resultat final, depenent de si aquest o l’anterior són espais.
    • Amb tantes substitucions com calgui de dos espais seguits a un.

    El codi per mesurar-ho és:

    from timeit import timeit
    
    def eliminar_espais_split_join (text: str) -> str:
        return " ".join(text.split())
    
    def eliminar_espais_posicio_a_posicio (text: str) -> str:
        anterior_es_espai = True
        sense_espais_redundants = ""
        for x in text:
            if x == " ":
                if not anterior_es_espai:
                    sense_espais_redundants += x
                    anterior_es_espai = True
            else:
                sense_espais_redundants += x
                anterior_es_espai = False
    
        if len(sense_espais_redundants) > 0:
            if sense_espais_redundants [-1] == " ":
                sense_espais_redundants = sense_espais_redundants[:-1]
        return sense_espais_redundants
    
    def eliminar_espais_replace (text: str) -> str:
        r2 = text
        while (r1:= r2.replace("  ", " ")) != r2:
                r2 = r1
        if len(r2) > 0:
            if r2[0] == " ":
                r2 = r2[1:]
        if len(r2) > 0:
            if r2[-1] == " ":
                r2 = r2[:-1]
        return r2
    
    TEXT_PROVA = "      Vivamus       quis        lacus     quis  sapien    elementum     finibus   et    sollicitudin nisi.   "
    
    assert (eliminar_espais_posicio_a_posicio (TEXT_PROVA) == eliminar_espais_split_join(TEXT_PROVA))
    assert (eliminar_espais_replace (TEXT_PROVA) == eliminar_espais_split_join(TEXT_PROVA))
    
    EXECUCIONS = 100_000
    
    temps = (timeit (lambda: eliminar_espais_split_join (TEXT_PROVA), number=EXECUCIONS),
             timeit (lambda: eliminar_espais_posicio_a_posicio (TEXT_PROVA), number=EXECUCIONS),
             timeit (lambda: eliminar_espais_replace(TEXT_PROVA), number=EXECUCIONS))
    
    temps_minim = min(temps)
    
    print (f"eliminar_espais_split_join: {temps [0] / temps_minim:.2f} vegades el mínim")
    print (f"eliminar_espais_posicio_a_posicio: {temps [1] / temps_minim:.2f} vegades el mínim")
    print (f"eliminar_espais_replace: {temps [2] / temps_minim:.2f} vegades el mínim")

    I el resultat:

    eliminar_espais_split_join: 1.00 vegades el mínim
    eliminar_espais_replace: 2.25 vegades el mínim
    eliminar_espais_posicio_a_posicio: 8.83 vegades el mínim

    He provat algunes variants, sense que influeixin significativament en els resultats:

    • Sense fer servir l’operador walrus (notació := al while) a eliminar_espais_replace.
    • Amb substitucions de 2 i 3 espais concatenades a eliminar_espais_replace.
    • Amb un índex per accedir als diferents caràcters a posicio_a_posicio.

    O sigui, he deixat l’split_join al codi, la manera més genuïna del Python és alhora la més ràpida.