]> pere.pagekite.me Git - homepage.git/blobdiff - blog/archive/2023/11/11.rss
Nytt bokforslag.
[homepage.git] / blog / archive / 2023 / 11 / 11.rss
index fcb14e497b4a4c2483144ca7e96d302638f3eecb..cdd3bcce3fa898d9581612dd8fb0eccfb1a463e3 100644 (file)
        <channel>
                <title>Petter Reinholdtsen - Entries from November 2023</title>
                <description>Entries from November 2023</description>
-                <link>https://people.skolelinux.org/pere/blog/</link>
+                <link>http://www.hungry.com/~pere/blog/</link>
 
        
+       <item>
+               <title>«Når «på» blir «pÃ¥»: Et reservoar av tegn sett fra depotet» i tidsskriftet Aksess</title>
+               <link>http://www.hungry.com/~pere/blog/_N_r__p___blir__p_____Et_reservoar_av_tegn_sett_fra_depotet__i_tidsskriftet_Aksess.html</link>        
+               <guid isPermaLink="true">http://www.hungry.com/~pere/blog/_N_r__p___blir__p_____Et_reservoar_av_tegn_sett_fra_depotet__i_tidsskriftet_Aksess.html</guid>
+                <pubDate>Wed, 15 Nov 2023 09:20:00 +0100</pubDate>
+               <description>&lt;p&gt;For noen uker siden skrev en kamerat og meg
+&lt;a href=&quot;https://www.aksess-tidsskrift.no/fordypning/175530&quot;&gt;en
+artikkel om tegnsett&lt;/a&gt; i
+&lt;a href=&quot;https://www.aksess-tidsskrift.no/&quot;&gt;arkivtidsskriftet
+Aksess&lt;/a&gt; både på web og i papirutgave nr. 3 2023.  Her er det som
+nettopp ble publisert.&lt;/p&gt;
+
+&lt;blockquote&gt;
+
+&lt;p&gt;&lt;strong&gt;Når «på» blir «pÃ¥»: Et reservoar av tegn sett fra
+depotet&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;av Thomas Sødring og Petter Reinholdtsen&lt;/p&gt;
+
+&lt;p&gt;De færreste av oss tenker over hva som skjer dypere i datamaskinen
+mens vi sitter der og skriver noe på tastaturet. Når du trykker på
+tasten «Å», så vises bokstaven Å. Men noen ganger blir det
+feil. Hvorfor det – og hva er viktig å være klar over i
+arkivsammenheng?&lt;/p&gt;
+
+&lt;p&gt;Dersom bokstaver tolkes forskjellig mellom systemer, blir det fort
+rot, dette kalles mojibake blant kjennere, etter det japanske
+uttrykket for tegnomforming. Det er en lang historie her som tidvis
+har vært preget av rot.  Noen husker kanskje tilbake til en tid der
+bokstavene æ, ø og å ofte var ødelagt i e-poster – et klassisk
+eksempel på tegnsettproblemstilling.&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_nå_og_før&quot;&gt;&lt;strong&gt;«Nå» og «før»&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;Tid er et skjult problem for depot fordi vi danner dokumentasjon i
+en kontekst som er preget av å være «nå».  Vår forståelse av verden og
+bruken av teknologi er utgangspunktet for denne konteksten. Tenk selv
+hvordan verden har utviklet seg de siste 20 årene, hva samfunnet er
+opptatt av, og hvordan vi bruker teknologi i hverdagen. Tid er et
+skjult problem fordi når vi trekker dokumentasjon ut av systemer og
+deponerer for langtidsbevaring, er konteksten til materialet «nå», men
+verden går videre. Ettersom teknologien og måten vi bruker den på,
+utvikler seg, blir «nå» til «før», og dokumentasjonen befinner seg
+snart i en «før»-kontekst.&lt;/p&gt;
+
+&lt;p&gt;Dette med «før» og «nå» i forhold til dokumentasjonens kontekst er
+noe vi er veldig lite bevisste på, men det er en problemstilling
+depotarkivene eier og forvalter.  En av disse utfordringene er hvorfor
+«Ø» ikke nødvendigvis er det samme som «Ø», og hvorfor det i det hele
+tatt gir mening å si noe sånt. Vi snakker her om noe som heter
+tegnsett, som er en avtalt måte å representere bokstaver, tall og
+andre symboler på slik at vi på en feilfri måte kan utveksle tekst
+mellom datasystemer.&lt;/p&gt;
+
+&lt;p&gt;Tegnsettproblemstillingen er satt sammen av fire fasetter;
+repertoar, representasjon, koding og uttegning.&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_repertoarer&quot;&gt;&lt;strong&gt;Repertoarer&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;Repertoar er en samling med tegn og symboler som kan
+representeres. Tenk norsk alfabet eller japanske piktogrammer, men
+også matematiske og elektroniske symboler. Bokstaven «stor a» kan være
+en oppføring i et slikt repertoar. For å kunne brukes i en datamaskin
+trenger hver oppføring i et slikt repertoar en representasjon, hvilket
+i datamaskinsammenheng betyr at det tilordnes et tall. Tallet kan
+lagres på ulike vis i en eller flere kodingsformater. For eksempel kan
+en skrive tallet ti som både 10, X og A, i henholdsvis
+titallssystemet, romertallssystemet og sekstentallssystemet.&lt;/p&gt;
+
+&lt;p&gt;Hvis en skal kunne lese inn filer og vite hvilket tall og hvilken
+representasjon og instans i et repertoar det er snakk om, så må en
+vite hvordan tallet er kodet. Sist, men ikke minst, for å kunne bruke
+symbolet til noe må det kunne være kjent hvordan det skal se ut eller
+tegnes på ark. Det finnes utallige skrifttyper med norske bokstaver,
+alle litt forskjellige, og skal en kunne tegne en stor A på skjermen,
+så må datamaskinen vite hva den skal tegne. Skrifttyper inneholder
+informasjon om hvordan ulike tall skal tegnes. De inneholder ikke
+alltid alle symbolene som er brukt i en tekst, hvilket gjør at ikke
+alle forståtte tegn vil kunne vises på skjerm eller ark.&lt;/p&gt;
+
+&lt;p&gt;Hver av disse fasettene må være avklart for å kunne ta vare på og vise
+frem tekst med en datamaskin. Kombinasjon av repertoar, representasjon
+og koding er det en kaller et tegnsett. Kombinasjonen av
+representasjon og uttegning kalles en skrifttype. De fleste
+skrifttyper har også informasjon om repertoar, men det finnes
+skrifttyper som kun kobler mellom tallkode og uttegning, uten å
+fortelle noe om hvordan tallkodene egentlig skal tolkes.&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_fra_ascii_til_iso_8859&quot;&gt;&lt;strong&gt;Fra ASCII til ISO-8859&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;Vi begynner historien med ASCII (American Standard Code for
+Information Interchange) som har en historie som spores tilbake til
+1963. Utgangspunktet til ASCII var at det kunne kode opp til 128
+forskjellige symboler i vanlig bruk i USA. De visuelle symbolene i
+ASCII er de små og store bokstavene (a til z og A til Z), tall (0 til
+9) og tegnsettingssymboler (for eksempel semikolon, komma og
+punktum). ASCII har også noen usynlige symboler som ble brukt for
+bl.a. kommunikasjon. Før ASCII var det for eksempel teleks-tegnsett
+med plass til bare 32 tegn og EBCDIC med plass til 256 tegn, alle med
+en helt annen rekkefølge på symbolene enn ASCII, men de har vært lite
+brukt de siste femti årene. Et eksempel på noen utvalgte symboler i
+repertoaret til ASCII vises i tabell 1.&lt;/p&gt;
+
+&lt;table align=&quot;center&quot; width=&quot;50%&quot;&gt;
+
+&lt;caption&gt;Tabell 1. Eksempel på utvalgte symboler hentet fra
+ASCII-tegnsettet. Kolonnen «Binær» viser symbolets verdi i
+totallssystemet (1 og 0 tall), mens kolonnen «Desimal» viser symbolets
+verdi i titallssystemet.&lt;/caption&gt;
+
+&lt;tbody&gt;
+&lt;tr&gt;
+&lt;th&gt;Grafisk&lt;/th&gt;
+&lt;th&gt;Binær&lt;/th&gt;
+&lt;th&gt;Desimal&lt;/th&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;A&lt;/td&gt;
+&lt;td&gt;1000001&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;65&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;M&lt;/td&gt;
+&lt;td&gt;1001101&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;77&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;Z&lt;/td&gt;
+&lt;td&gt;1011010&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;90&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;a&lt;/td&gt;
+&lt;td&gt;1100001&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;97&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;m&lt;/td&gt;
+&lt;td&gt;1101101&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;109&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;z&lt;/td&gt;
+&lt;td&gt;1111010&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;122&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;0&lt;/td&gt;
+&lt;td&gt;0110000&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;48&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;9&lt;/td&gt;
+&lt;td&gt;0111001&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;58&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;;&lt;/td&gt;
+&lt;td&gt;0111011&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;59&lt;/td&gt;
+&lt;/tr&gt;
+&lt;/tbody&gt;
+&lt;/table&gt;
+
+&lt;p&gt;Det opprinnelige ASCII-tegnsettet ble også omtalt som ASCII-7 og
+brukte 7 bits (0 og 1) for å representere symboler. Datamaskiner er
+ofte konfigurert til å jobbe med enheter der bits er gruppert som 4
+eller 8 bits . Det lå en mulighet i å ta i bruk bit åtte. En slik
+endring ville gjøre det mulig for datamaskiner å øke antall symboler
+de kunne representere, noe som ga en økning fra 128 forskjellige
+symboler til 256 forskjellige symboler. Det ble åpnet for å innlemme
+de nordiske bokstavene sammen med ASCII, og dette ble etter hvert
+standardisert som ISO-8859-1. Tabell 2 viser deler av ISO-8859-1 som
+støtter de norske bokstavene.&lt;/p&gt;
+
+&lt;p&gt;Det sier seg selv at muligheten til å representere inntil 256 symboler
+ikke holder når vi snakker om en global verden, og det ble gjort et
+standardiseringsløp som tok utgangspunkt i ASCII-7 med en utvidelse
+til å bruke den åttende biten for ulike språkgrupper. Denne standarden
+heter ISO-8859 og er inndelt i opptil 16 varianter, altså fra
+ISO-8859-1 til ISO-8859-16.&lt;/p&gt;
+
+&lt;table align=&quot;center&quot; width=&quot;50%&quot;&gt;
+
+&lt;caption&gt;Tabell 2. Koding av de norske symbolene slik de er definert i
+ISO-8859-1 tegnsettet.&lt;/caption&gt;
+
+&lt;tbody&gt;
+&lt;tr&gt;
+&lt;th&gt;Grafisk&lt;/th&gt;
+&lt;th&gt;Binær&lt;/th&gt;
+&lt;th&gt;Desimal&lt;/th&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;11000110&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;198&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;11011000&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;216&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;11000101&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;197&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;11100110&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;230&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;11111000&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;248&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;11100101&lt;/td&gt;
+&lt;td align=&quot;right&quot;&gt;229&lt;/td&gt;
+&lt;/tr&gt;
+&lt;/tbody&gt;
+&lt;/table&gt;
+
+&lt;p&gt;Norske tegn er definert i ISO-8859-1, som også omtales som Latin 1, de
+fleste samiske tegn er definert i ISO-8859-4 (Latin 4) mens tilgang
+til €-symbolet kom med ISO-8859-15 (Latin 9). ISO-8859-15 er en
+revisjon av ISO-8859-1 som fjerner noen lite brukte symboler og
+erstatter bokstaver som er mer brukt, og introduserer €-symbolet.  Det
+er viktig å merke at alle ISO-8859-variantene har overlapp med
+ASCII-7, noe som ga samvirke med de engelskspråklige landene som ikke
+trengte å gjøre noe. Det innebærer også at de første 128 verdiene i
+ISO-8859-variantene representerer de samme symbolene. Det er først når
+du kommer til tolkningen av de resterende 128 verdiene med nummer 128
+til 255, at det oppsto tolkningsutfordringer mellom
+ISO-8859-variantene.&lt;/p&gt;
+
+&lt;p&gt;ISO-8859-verdenen fungerte godt så lenge tegnsettet som ble brukt når
+innhold ble skapt, også ble brukt når innhold ble gjengitt og du ikke
+trengte å kombinere innhold fra forskjellige tegnsett i samme
+dokument.  Utfordringen med bruken av ISO-8859-variantene ble raskt
+tydelig i en mer globalisert verden med utveksling av tekst på tvers
+av landegrenser der tekstlig innhold i dokumenter, e-poster og
+websider kunne bli skrevet med ett tegnsett og gjengitt med et annet
+tegnsett.&lt;/p&gt;
+
+&lt;table align=&quot;center&quot; width=&quot;60%&quot;&gt;
+
+&lt;caption&gt;Tabell 3. Viser tolkning av verdiene som er tilegnet de
+norske symbolene i ISO-8859-1 i de andre ISO 8859-variatene. Merk
+ISO-8859-12 ikke finnes da arbeidet ble avsluttet.&lt;sup&gt;[&lt;a id=&quot;tegnsett_access_footnoteref_1&quot; href=&quot;#tegnsett_access_footnotedef_1&quot; title=&quot;View footnote.&quot;&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;/caption&gt;
+
+&lt;tbody&gt;
+&lt;tr&gt;
+&lt;th&gt;Binærverdi&lt;/th&gt;
+&lt;th&gt;1&lt;/th&gt;
+&lt;th&gt;2&lt;/th&gt;
+&lt;th&gt;3&lt;/th&gt;
+&lt;th&gt;4&lt;/th&gt;
+&lt;th&gt;5&lt;/th&gt;
+&lt;th&gt;6&lt;/th&gt;
+&lt;th&gt;7&lt;/th&gt;
+&lt;th&gt;8&lt;/th&gt;
+&lt;th&gt;9&lt;/th&gt;
+&lt;th&gt;10&lt;/th&gt;
+&lt;th&gt;11&lt;/th&gt;
+&lt;th&gt;13&lt;/th&gt;
+&lt;th&gt;14&lt;/th&gt;
+&lt;th&gt;15&lt;/th&gt;
+&lt;th&gt;16&lt;/th&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;11000110&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;Ć&lt;/td&gt;
+&lt;td&gt;Ĉ&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;Ц&lt;/td&gt;
+&lt;td&gt;ئ&lt;/td&gt;
+&lt;td&gt;Ζ&lt;/td&gt;
+&lt;td&gt;&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;ฦ&lt;/td&gt;
+&lt;td&gt;Ę&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;td&gt;Æ&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;11011000&lt;/td&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;Ř&lt;/td&gt;
+&lt;td&gt;Ĝ&lt;/td&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;и&lt;/td&gt;
+&lt;td&gt;ظ&lt;/td&gt;
+&lt;td&gt;Ψ&lt;/td&gt;
+&lt;td&gt;&lt;/td&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;ุ&lt;/td&gt;
+&lt;td&gt;Ų&lt;/td&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;Ø&lt;/td&gt;
+&lt;td&gt;Ű&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;11000101&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;Ĺ&lt;/td&gt;
+&lt;td&gt;Ċ&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;Х&lt;/td&gt;
+&lt;td&gt;إ&lt;/td&gt;
+&lt;td&gt;Ε&lt;/td&gt;
+&lt;td&gt;&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;ล&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;Å&lt;/td&gt;
+&lt;td&gt;Ć&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;11100110&lt;/td&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;ć&lt;/td&gt;
+&lt;td&gt;ĉ&lt;/td&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;ц&lt;/td&gt;
+&lt;td&gt;ن&lt;/td&gt;
+&lt;td&gt;ζ&lt;/td&gt;
+&lt;td&gt;ז&lt;/td&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;ๆ&lt;/td&gt;
+&lt;td&gt;ę&lt;/td&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;æ&lt;/td&gt;
+&lt;td&gt;v&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;11111000&lt;/td&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;ř&lt;/td&gt;
+&lt;td&gt;ĝ&lt;/td&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;ј&lt;/td&gt;
+&lt;td&gt;&lt;/td&gt;
+&lt;td&gt;ψ&lt;/td&gt;
+&lt;td&gt;ר&lt;/td&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;๘&lt;/td&gt;
+&lt;td&gt;ų&lt;/td&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;ø&lt;/td&gt;
+&lt;td&gt;ű&lt;/td&gt;
+&lt;/tr&gt;
+&lt;tr&gt;
+&lt;td&gt;11100101&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;ĺ&lt;/td&gt;
+&lt;td&gt;ċ&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;х&lt;/td&gt;
+&lt;td&gt;م&lt;/td&gt;
+&lt;td&gt;ε&lt;/td&gt;
+&lt;td&gt;ו&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;ๅ&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;å&lt;/td&gt;
+&lt;td&gt;ć&lt;/td&gt;
+&lt;/tr&gt;
+&lt;/tbody&gt;
+&lt;/table&gt;
+
+&lt;p&gt;Denne problemstillingen er illustrert i tabell 3, der vi ser verdiene
+tilegnet de norske symbolene i ISO-8859-1 i kolonne «1». I de øvrige
+kolonnene ser vi hvilket symbol verdien får i de andre
+ISO-8859-variantene. Tar vi utgangspunkt i tabell 3, kan vi se at
+ordet lærlingspørsmål gjengitt med ISO-8859-2 (kolonne 2) blir
+lćrlingspřrsmĺl, mens det blir lζrlingspψrsmεl med ISO- 8859-7
+(kolonne 7). Med ISO-8859-2 blir «æ» til «ć», «ø» til «ř» og «å» til
+ «ĺ». I ISO-8859-7 blir «æ» til «ζ», «ø» til «ψ», mens «å» blir «ε».&lt;/p&gt;
+
+&lt;p&gt;Det er egentlig ingen utfordring med dette så lenge du vet hvilket
+tegnsett innholdet ditt er representert med, og det ikke har skjedd
+omforminger som du ikke er klar over. Det er det siste som er
+problematisk, spesielt de datasystemene som har vært i bruk de siste
+20 årene, som ikke har noe innebygd funksjonalitet for å forvalte
+tegnsettproblematikken. Et godt eksempel på dette er
+Microsoft-tegnsettet Windows-1252, som ble forvekslet som 100 %
+kompatibel med ISO-8859-1, men hadde byttet ut plassene fra 127 til
+159. Historisk vil det finnes en del variasjon i hvilket tegnsett som
+har vært i bruk, og hvor vellykket konvertering mellom tegnsett har
+vært.&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_unicode_som_løsning&quot;&gt;&lt;strong&gt;Unicode som løsning&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;Tegnsettforvirring ble etter hvert et irritasjonsmoment og
+samvirkeproblem. Ofte fikk man en e-post der æøå var erstattet av rare
+symboler fordi e-posten hadde vært innom et eller annet datasystem som
+ikke brukte samme tegnsett.&lt;/p&gt;
+
+&lt;p&gt;For å løse dette samvirkeproblemet for tegnsett ble det startet et
+arbeid og en ny standard så dagens lys etter hvert. Denne standarden
+fikk navnet Unicode (ISO/ IEC 10646) og skulle resultere i et tegnsett
+som alle skulle være enige om. Unicode er et repertoar og en
+representasjon, dvs. navngivning og tilordning av tallverdi til alle
+symboler i bruk i verden i dag.  Oppføringer i Unicode skrives gjerne
+U+XXXX der XXXX er tallkoden i sekstentallssystemet som oppføringen
+har i Unicode-katalogen. Her finner vi tegn brukt av både levende og
+døde språk, konstruerte språk, tekniske symboler, morsomme tegninger
+(såkalte emojier) og tegn ingen vet hva betyr eller skal brukes
+til. Et morsomt eksempel er i nettartikkelen: U+237C ⍼ RIGHT ANGLE
+WITH DOWNWARDS ZIGZAG ARROW, av Jonathan Chan.&lt;sup&gt;[&lt;a id=&quot;tegnsett_access_footnoteref_2&quot; href=&quot;#tegnsett_access_footnotedef_2&quot; title=&quot;View footnote.&quot;&gt;2&lt;/a&gt;]&lt;/sup&gt;&lt;/p&gt;
+
+&lt;p&gt;Sammen med Unicode kom det tre måter å kode disse tallene på; UTF-8,
+UTF-16 og UTF-32. Av datatekniske årsaker er UTF-8 mye brukt, spesielt
+når det gjelder utveksling av tekst over Internett, mens UTF-16 er
+brukt en del til tekstfiler lagret på Windows. En utfordring med
+Unicode og UTF-variantene er at disse gir flere måter å kode samme
+symbol på med en kombinasjonsmekanisme. Dette kan gi utfordringer ved
+søk, hvis en skal søke etter et ord som har ett eller flere symboler
+som kan skrives på ulikt vis, så er det ikke sikkert at søkesystemet
+vil finne alle forekomster. For eksempel kan bokstaven U+00F8 «Latin
+Small Letter O with Stroke» kodes som den tradisjonelle norske tegnet
+ø, men også som o kombinert med skråstrek U+0338. Begge deler er
+gyldig bruk av Unicode, selv om det er tradisjon for å foretrekke å
+«normalisere» kombinasjoner som enkelttegn der det er mulig, nettopp
+for å forenkle søk.&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_bare_unicode_fremover&quot;&gt;&lt;strong&gt;Bare Unicode fremover&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;Forvaltningens bruk av tegnsett er regulert i Forskrift om
+IT-standarder i offentlig forvaltning&lt;sup&gt;[&lt;a id=&quot;tegnsett_access_footnoteref_3&quot; href=&quot;#tegnsett_access_footnotedef_3&quot; title=&quot;View footnote.&quot;&gt;3&lt;/a&gt;]&lt;/sup&gt;. Her står det: «Ved all
+utveksling av informasjon mellom forvaltningsorganer og fra
+forvaltningsorgan til innbyggere og næringsliv skal tegnsettstandarden
+ISO/IEC 10646 representert ved UTF8 benyttes.»  Det er forskjellige
+bruksområder til UTF-8, UTF-16 og UTF-32, men UTF-8 er kodingen vi
+kjenner mest til.  Det er flere grunner at UTF-8 «vant» konkurransen
+til å bli den utvalgte. Den kanskje viktigste er at UTF-8 er fullt
+samvirkende med ASCII-7, slik at den engelskspråklige delen av verden
+kunne rulle ut UTF-8 uten å merke noe forskjell. En tekstfil med kun
+ASCII-tekst vil være identisk på disken hvis den lagres som UTF-8 og
+ASCII. UTF-16 og UTF-32 byr på noen optimaliseringer som gjør dem
+relevant for spesifikke problemområder, men for det meste vil vi aldri
+oppleve disse standardene på nært hold i hverdagen. Det er uansett kun
+bruken av UTF-8 som er lovregulert i Norge.&lt;/p&gt;
+
+&lt;p&gt;Det er ikke slik at hele verden bruker ISO/IEC 10646 og UTF-8. Kina
+har egne standarder for tegnsett, mye brukt er GB 18030, som er
+Unicode med en annen koding enn UTF-8, mens Taiwan og andre asiatiske
+land gjerne bruker Big5 eller andre tegnsett.&lt;/p&gt;
+
+&lt;p&gt;UTF-8 er dominerende i Norge, men det er tidsperioder der forskjellige
+datasystemer utvekslet data i henhold til ISO-8859-1, ISO-8859-15,
+Windows-1252, Codepage 865 og ISO-646-60 / Codepage 1016 mens
+overgangen til UTF-8 pågikk. Det er ikke slik at et datasystem enkelt
+kan tvinges til å bruke et tegnsett, da det er flere lag i et
+datasystem som må settes opp til å bruke riktig tegnsett, og
+tegnsettproblemet fort oppstår når det er et eller annet i
+datasystemet som bruker feil tegnsett.&lt;/p&gt;
+
+&lt;p&gt;Et klassisk eksempel på problemet er en utveksling av tekst mellom to
+systemer der teksten i utgangspunktet er kodet i UTF-8, men går
+gjennom noe som er ISO-8859-1 underveis. Dette kan vises med at ordet
+«på» i et slik scenario ender opp som «pÃ¥». Det er mulig å spore
+dette tilbake til verdiene symbolene er tilordnet i tegnsettene. «på»
+blir til «pÃ¥» fordi «å» i UTF-8 er representert med U+C3AF, og dersom
+vi ser på hva disse verdiene representerer, ser vi at
+sekstentallssystemverdien C3 er 1100 0011 i totallssystemet og
+symbolet med dette tallet i ISO-8859-1 er Ã.&lt;/p&gt;
+
+&lt;p&gt;Vi ser det samme med sekstentallssystemverdien A5, som er 1010 0101 i
+totallssystemet, og tilsvarende symbol i ISO-8859-1 er ¥. Slik
+mojibake kan lett skje hvis «på» i utgangspunktet var representert med
+UTF-8, men ble behandlet med et system som bruker ISO-8859-1. Det er
+ingen automatikk i å fange opp slike ødeleggelser mens tekstlig
+innhold utveksles mellom datasystemer.&lt;/p&gt;
+
+&lt;p&gt;En utfordring for depotarkivene er at bruken av tegnsett ikke alltid
+har vært regulert, og at det kan finnes flere dokumentasjonssamlinger
+som er opprettet med varierende tegnsett før gjeldende forskrift
+inntraff – uten at det er mulig å avlede fra filene hvilket tegnsett
+som ble brukt. Et eksempel på dette er €-symbolet, som kom først etter
+at ISO-8859-1 var tatt i bruk. Det kan bli en utfordring for et
+depotarkiv, men så lenge det er kjent hvilket tegnsett var i bruk, så
+bør det gå bra.  Riksarkivarens
+forskrift&lt;sup&gt;[&lt;a id=&quot;tegnsett_access_footnoteref_4&quot; href=&quot;#tegnsett_access_footnotedef_4&quot; title=&quot;View footnote.&quot;&gt;4&lt;/a&gt;]&lt;/sup&gt;
+formaliserer dette ved å kreve følgende:&lt;/p&gt;
+
+&lt;blockquote&gt;
+&lt;p&gt;§ 5-11. Tegnsett i arkivuttrekk&lt;/p&gt;
+
+&lt;ol&gt;
+  &lt;li&gt;Arkivuttrekk og medfølgende struktur- og innholdsbeskrivelser skal
+      overføres som ren tekst i ukryptert form, og benytte godkjent
+      tegnsett.&lt;/li&gt;
+
+  &lt;li&gt;Godkjente tegnsett er:
+    &lt;ol&gt;
+      &lt;li&gt;Unicode UTF-8&lt;br&gt;
+          (ISO/IEC 10646-1:2000 Annex D)&lt;/li&gt;
+      &lt;li&gt;ISO 8859-1:1998, Latin 1&lt;/li&gt;
+      &lt;li&gt;ISO 8859-4:1998, Latin 4 for samiske tegn.&lt;/li&gt;
+    &lt;/ol&gt;&lt;/li&gt;
+
+  &lt;li&gt;Andre tegnsett aksepteres bare etter avtale med Arkivverket.&lt;/li&gt;
+&lt;/ol&gt;
+&lt;/blockquote&gt;
+
+&lt;p id=&quot;tegnsett_access_ditt_ansvar&quot;&gt;&lt;strong&gt;Ditt ansvar&lt;/strong&gt;&lt;/p&gt;
+
+&lt;p&gt;På mange måter burde ikke tegnsett være et problem i 2023, men sånn er
+det nok ikke. Land som har oppgradert til UTF-8 som primærtegnsett for
+utveksling av tekstlig innhold, begrenser problematikken betraktelig,
+men globalt sett så er tegnsettutfordringen ikke løst fordi ikke alle
+er enige om å bruke samme tegnsett.  Det kan være geopolitiske eller
+kulturelle hensyn som ligger til grunn for dette.&lt;/p&gt;
+
+&lt;p&gt;Det er uansett verdt å merke at selv om bruken av UTF-8 skulle bli
+100% utbredt, så er det et historisk perspektiv (ASCII-7,
+ISO-8859-variantene, UTF-8) her som gjør tegnsett til et problemområde
+arkivarene må forstå og håndtere.  Som danningsarkivar har du et
+ansvar for å vite hvilket tegnsett systemene og databasene dere
+forvalter, er i samsvar med. Det er noe IT-avdelingen din eller
+programvareleverandørene enkelt skal kunne svare på, og svaret skal
+være UTF-8 for alle nye systemer.&lt;/p&gt;
+
+&lt;hr&gt;
+
+&lt;p id=&quot;tegnsett_access_footnotedef_1&quot;&gt;&lt;a href=&quot;#tegnsett_access_footnoteref_1&quot;&gt;1&lt;/a&gt;. Tegnsettkilde &lt;a href=&quot;https://en.wikipedia.org/wiki/ISO/IEC_8859&quot;&gt;https://en.wikipedia.org/wiki/ISO/IEC_8859&lt;/a&gt;&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_footnotedef_2&quot;&gt;&lt;a href=&quot;#tegnsett_access_footnoteref_2&quot;&gt;2&lt;/a&gt;. &lt;a href=&quot;https://ionathan.ch/2022/04/09/angzarr.html&quot;&gt;https://ionathan.ch/2022/04/09/angzarr.html&lt;/a&gt;&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_footnotedef_3&quot;&gt;&lt;a href=&quot;#tegnsett_access_footnoteref_3&quot;&gt;3&lt;/a&gt;. &lt;a href=&quot;https://lovdata.no/dokument/SF/forskrift/2013-04-05-959/%C2%A78#%C2%A78&quot;&gt;https://lovdata.no/dokument/SF/forskrift/2013-04-05-959/%C2%A78#%C2%A78&lt;/a&gt;&lt;/p&gt;
+
+&lt;p id=&quot;tegnsett_access_footnotedef_4&quot;&gt;&lt;a href=&quot;#tegnsett_access_footnoteref_4&quot;&gt;4&lt;/a&gt;. &lt;a href=&quot;https://lovdata.no/forskrift/2017-12-19-2286/§5-11&quot;&gt;https://lovdata.no/forskrift/2017-12-19-2286/§5-11&lt;/a&gt;&lt;/p&gt;
+
+&lt;/blockquote&gt;
+
+&lt;p&gt;For øvrig burde varsleren Edward Snowden få politisk asyl i Norge.&lt;/p&gt;
+
+&lt;p&gt;Som vanlig, hvis du bruker Bitcoin og ønsker å vise din støtte til
+det jeg driver med, setter jeg pris på om du sender Bitcoin-donasjoner
+til min adresse
+&lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;. Merk,
+betaling med bitcoin er ikke anonymt. :)&lt;/p&gt;
+</description>
+       </item>
+       
+       <item>
+               <title>New and improved sqlcipher in Debian for accessing Signal database</title>
+               <link>http://www.hungry.com/~pere/blog/New_and_improved_sqlcipher_in_Debian_for_accessing_Signal_database.html</link>        
+               <guid isPermaLink="true">http://www.hungry.com/~pere/blog/New_and_improved_sqlcipher_in_Debian_for_accessing_Signal_database.html</guid>
+                <pubDate>Sun, 12 Nov 2023 12:00:00 +0100</pubDate>
+               <description>&lt;p&gt;For a while now I wanted to have direct access to the
+&lt;a href=&quot;https://signal.org/&quot;&gt;Signal&lt;/a&gt; database of messages and
+channels of my Desktop edition of Signal.  I prefer the enforced end
+to end encryption of Signal these days for my communication with
+friends and family, to increase the level of safety and privacy as
+well as raising the cost of the mass surveillance government and
+non-government entities practice these days.  In August I came across
+a nice
+&lt;a href=&quot;https://www.yoranbrondsema.com/post/the-guide-to-extracting-statistics-from-your-signal-conversations/&quot;&gt;recipe
+on how to use sqlcipher to extract statistics from the Signal
+database&lt;/a&gt; explaining how to do this.  Unfortunately this did not
+work with the version of sqlcipher in Debian.  The
+&lt;a href=&quot;http://tracker.debian.org/sqlcipher/&quot;&gt;sqlcipher&lt;/a&gt;
+package is a &quot;fork&quot; of the sqlite package with added support for
+encrypted databases.  Sadly the current Debian maintainer
+&lt;a href=&quot;https://bugs.debian.org/961598&quot;&gt;announced more than three
+years ago that he did not have time to maintain sqlcipher&lt;/a&gt;, so it
+seemed unlikely to be upgraded by the maintainer.  I was reluctant to
+take on the job myself, as I have very limited experience maintaining
+shared libraries in Debian.  After waiting and hoping for a few
+months, I gave up the last  week, and set out to update the package.  In
+the process I orphaned it to make it more obvious for the next person
+looking at it that the package need proper maintenance.&lt;/p&gt;
+
+&lt;p&gt;The version in Debian was around five years old, and quite a lot of
+changes had taken place upstream into the Debian maintenance git
+repository.  After spending a few days importing the new upstream
+versions, realising that upstream did not care much for SONAME
+versioning as I saw library symbols being both added and removed with
+minor version number changes to the project, I concluded that I had to
+do a SONAME bump of the library package to avoid surprising the
+reverse dependencies.  I even added a simple
+autopkgtest script to ensure the package work as intended.  Dug deep
+into the hole of learning shared library maintenance, I set out a few
+days ago to upload the new version to Debian experimental to see what
+the quality assurance framework in Debian had to say about the result.
+The feedback told me the pacakge was not too shabby, and yesterday I
+uploaded the latest version to Debian unstable.  It should enter
+testing today or tomorrow, perhaps delayed by
+&lt;a href=&quot;https://bugs.debian.org/1055812&quot;&gt;a small library
+transition&lt;/a&gt;.&lt;/p&gt;
+
+&lt;p&gt;Armed with a new version of sqlcipher, I can now have a look at the
+SQL database in ~/.config/Signal/sql/db.sqlite.  First, one need to
+fetch the encryption key from the Signal configuration using this
+simple JSON extraction command:&lt;/p&gt;
+
+&lt;pre&gt;/usr/bin/jq -r &#39;.&quot;key&quot;&#39; ~/.config/Signal/config.json&lt;/pre&gt;
+
+&lt;p&gt;Assuming the result from that command is &#39;secretkey&#39;, which is a
+hexadecimal number representing the key used to encrypt the database.
+Next, one can now connect to the database and inject the encryption
+key for access via SQL to fetch information from the database.  Here
+is an example dumping the database structure:&lt;/p&gt;
+
+&lt;pre&gt;
+% sqlcipher ~/.config/Signal/sql/db.sqlite
+sqlite&gt; PRAGMA key = &quot;x&#39;secretkey&#39;&quot;;
+sqlite&gt; .schema
+CREATE TABLE sqlite_stat1(tbl,idx,stat);
+CREATE TABLE conversations(
+      id STRING PRIMARY KEY ASC,
+      json TEXT,
+
+      active_at INTEGER,
+      type STRING,
+      members TEXT,
+      name TEXT,
+      profileName TEXT
+    , profileFamilyName TEXT, profileFullName TEXT, e164 TEXT, serviceId TEXT, groupId TEXT, profileLastFetchedAt INTEGER);
+CREATE TABLE identityKeys(
+      id STRING PRIMARY KEY ASC,
+      json TEXT
+    );
+CREATE TABLE items(
+      id STRING PRIMARY KEY ASC,
+      json TEXT
+    );
+CREATE TABLE sessions(
+      id TEXT PRIMARY KEY,
+      conversationId TEXT,
+      json TEXT
+    , ourServiceId STRING, serviceId STRING);
+CREATE TABLE attachment_downloads(
+    id STRING primary key,
+    timestamp INTEGER,
+    pending INTEGER,
+    json TEXT
+  );
+CREATE TABLE sticker_packs(
+    id TEXT PRIMARY KEY,
+    key TEXT NOT NULL,
+
+    author STRING,
+    coverStickerId INTEGER,
+    createdAt INTEGER,
+    downloadAttempts INTEGER,
+    installedAt INTEGER,
+    lastUsed INTEGER,
+    status STRING,
+    stickerCount INTEGER,
+    title STRING
+  , attemptedStatus STRING, position INTEGER DEFAULT 0 NOT NULL, storageID STRING, storageVersion INTEGER, storageUnknownFields BLOB, storageNeedsSync
+      INTEGER DEFAULT 0 NOT NULL);
+CREATE TABLE stickers(
+    id INTEGER NOT NULL,
+    packId TEXT NOT NULL,
+
+    emoji STRING,
+    height INTEGER,
+    isCoverOnly INTEGER,
+    lastUsed INTEGER,
+    path STRING,
+    width INTEGER,
+
+    PRIMARY KEY (id, packId),
+    CONSTRAINT stickers_fk
+      FOREIGN KEY (packId)
+      REFERENCES sticker_packs(id)
+      ON DELETE CASCADE
+  );
+CREATE TABLE sticker_references(
+    messageId STRING,
+    packId TEXT,
+    CONSTRAINT sticker_references_fk
+      FOREIGN KEY(packId)
+      REFERENCES sticker_packs(id)
+      ON DELETE CASCADE
+  );
+CREATE TABLE emojis(
+    shortName TEXT PRIMARY KEY,
+    lastUsage INTEGER
+  );
+CREATE TABLE messages(
+        rowid INTEGER PRIMARY KEY ASC,
+        id STRING UNIQUE,
+        json TEXT,
+        readStatus INTEGER,
+        expires_at INTEGER,
+        sent_at INTEGER,
+        schemaVersion INTEGER,
+        conversationId STRING,
+        received_at INTEGER,
+        source STRING,
+        hasAttachments INTEGER,
+        hasFileAttachments INTEGER,
+        hasVisualMediaAttachments INTEGER,
+        expireTimer INTEGER,
+        expirationStartTimestamp INTEGER,
+        type STRING,
+        body TEXT,
+        messageTimer INTEGER,
+        messageTimerStart INTEGER,
+        messageTimerExpiresAt INTEGER,
+        isErased INTEGER,
+        isViewOnce INTEGER,
+        sourceServiceId TEXT, serverGuid STRING NULL, sourceDevice INTEGER, storyId STRING, isStory INTEGER
+        GENERATED ALWAYS AS (type IS &#39;story&#39;), isChangeCreatedByUs INTEGER NOT NULL DEFAULT 0, isTimerChangeFromSync INTEGER
+        GENERATED ALWAYS AS (
+          json_extract(json, &#39;$.expirationTimerUpdate.fromSync&#39;) IS 1
+        ), seenStatus NUMBER default 0, storyDistributionListId STRING, expiresAt INT
+        GENERATED ALWAYS
+        AS (ifnull(
+          expirationStartTimestamp + (expireTimer * 1000),
+          9007199254740991
+        )), shouldAffectActivity INTEGER
+        GENERATED ALWAYS AS (
+          type IS NULL
+          OR
+          type NOT IN (
+            &#39;change-number-notification&#39;,
+            &#39;contact-removed-notification&#39;,
+            &#39;conversation-merge&#39;,
+            &#39;group-v1-migration&#39;,
+            &#39;keychange&#39;,
+            &#39;message-history-unsynced&#39;,
+            &#39;profile-change&#39;,
+            &#39;story&#39;,
+            &#39;universal-timer-notification&#39;,
+            &#39;verified-change&#39;
+          )
+        ), shouldAffectPreview INTEGER
+        GENERATED ALWAYS AS (
+          type IS NULL
+          OR
+          type NOT IN (
+            &#39;change-number-notification&#39;,
+            &#39;contact-removed-notification&#39;,
+            &#39;conversation-merge&#39;,
+            &#39;group-v1-migration&#39;,
+            &#39;keychange&#39;,
+            &#39;message-history-unsynced&#39;,
+            &#39;profile-change&#39;,
+            &#39;story&#39;,
+            &#39;universal-timer-notification&#39;,
+            &#39;verified-change&#39;
+          )
+        ), isUserInitiatedMessage INTEGER
+        GENERATED ALWAYS AS (
+          type IS NULL
+          OR
+          type NOT IN (
+            &#39;change-number-notification&#39;,
+            &#39;contact-removed-notification&#39;,
+            &#39;conversation-merge&#39;,
+            &#39;group-v1-migration&#39;,
+            &#39;group-v2-change&#39;,
+            &#39;keychange&#39;,
+            &#39;message-history-unsynced&#39;,
+            &#39;profile-change&#39;,
+            &#39;story&#39;,
+            &#39;universal-timer-notification&#39;,
+            &#39;verified-change&#39;
+          )
+        ), mentionsMe INTEGER NOT NULL DEFAULT 0, isGroupLeaveEvent INTEGER
+        GENERATED ALWAYS AS (
+          type IS &#39;group-v2-change&#39; AND
+          json_array_length(json_extract(json, &#39;$.groupV2Change.details&#39;)) IS 1 AND
+          json_extract(json, &#39;$.groupV2Change.details[0].type&#39;) IS &#39;member-remove&#39; AND
+          json_extract(json, &#39;$.groupV2Change.from&#39;) IS NOT NULL AND
+          json_extract(json, &#39;$.groupV2Change.from&#39;) IS json_extract(json, &#39;$.groupV2Change.details[0].aci&#39;)
+        ), isGroupLeaveEventFromOther INTEGER
+        GENERATED ALWAYS AS (
+          isGroupLeaveEvent IS 1
+          AND
+          isChangeCreatedByUs IS 0
+        ), callId TEXT
+        GENERATED ALWAYS AS (
+          json_extract(json, &#39;$.callId&#39;)
+        ));
+CREATE TABLE sqlite_stat4(tbl,idx,neq,nlt,ndlt,sample);
+CREATE TABLE jobs(
+        id TEXT PRIMARY KEY,
+        queueType TEXT STRING NOT NULL,
+        timestamp INTEGER NOT NULL,
+        data STRING TEXT
+      );
+CREATE TABLE reactions(
+        conversationId STRING,
+        emoji STRING,
+        fromId STRING,
+        messageReceivedAt INTEGER,
+        targetAuthorAci STRING,
+        targetTimestamp INTEGER,
+        unread INTEGER
+      , messageId STRING);
+CREATE TABLE senderKeys(
+        id TEXT PRIMARY KEY NOT NULL,
+        senderId TEXT NOT NULL,
+        distributionId TEXT NOT NULL,
+        data BLOB NOT NULL,
+        lastUpdatedDate NUMBER NOT NULL
+      );
+CREATE TABLE unprocessed(
+        id STRING PRIMARY KEY ASC,
+        timestamp INTEGER,
+        version INTEGER,
+        attempts INTEGER,
+        envelope TEXT,
+        decrypted TEXT,
+        source TEXT,
+        serverTimestamp INTEGER,
+        sourceServiceId STRING
+      , serverGuid STRING NULL, sourceDevice INTEGER, receivedAtCounter INTEGER, urgent INTEGER, story INTEGER);
+CREATE TABLE sendLogPayloads(
+        id INTEGER PRIMARY KEY ASC,
+
+        timestamp INTEGER NOT NULL,
+        contentHint INTEGER NOT NULL,
+        proto BLOB NOT NULL
+      , urgent INTEGER, hasPniSignatureMessage INTEGER DEFAULT 0 NOT NULL);
+CREATE TABLE sendLogRecipients(
+        payloadId INTEGER NOT NULL,
+
+        recipientServiceId STRING NOT NULL,
+        deviceId INTEGER NOT NULL,
+
+        PRIMARY KEY (payloadId, recipientServiceId, deviceId),
+
+        CONSTRAINT sendLogRecipientsForeignKey
+          FOREIGN KEY (payloadId)
+          REFERENCES sendLogPayloads(id)
+          ON DELETE CASCADE
+      );
+CREATE TABLE sendLogMessageIds(
+        payloadId INTEGER NOT NULL,
+
+        messageId STRING NOT NULL,
+
+        PRIMARY KEY (payloadId, messageId),
+
+        CONSTRAINT sendLogMessageIdsForeignKey
+          FOREIGN KEY (payloadId)
+          REFERENCES sendLogPayloads(id)
+          ON DELETE CASCADE
+      );
+CREATE TABLE preKeys(
+        id STRING PRIMARY KEY ASC,
+        json TEXT
+      , ourServiceId NUMBER
+        GENERATED ALWAYS AS (json_extract(json, &#39;$.ourServiceId&#39;)));
+CREATE TABLE signedPreKeys(
+        id STRING PRIMARY KEY ASC,
+        json TEXT
+      , ourServiceId NUMBER
+        GENERATED ALWAYS AS (json_extract(json, &#39;$.ourServiceId&#39;)));
+CREATE TABLE badges(
+        id TEXT PRIMARY KEY,
+        category TEXT NOT NULL,
+        name TEXT NOT NULL,
+        descriptionTemplate TEXT NOT NULL
+      );
+CREATE TABLE badgeImageFiles(
+        badgeId TEXT REFERENCES badges(id)
+          ON DELETE CASCADE
+          ON UPDATE CASCADE,
+        &#39;order&#39; INTEGER NOT NULL,
+        url TEXT NOT NULL,
+        localPath TEXT,
+        theme TEXT NOT NULL
+      );
+CREATE TABLE storyReads (
+        authorId STRING NOT NULL,
+        conversationId STRING NOT NULL,
+        storyId STRING NOT NULL,
+        storyReadDate NUMBER NOT NULL,
+
+        PRIMARY KEY (authorId, storyId)
+      );
+CREATE TABLE storyDistributions(
+        id STRING PRIMARY KEY NOT NULL,
+        name TEXT,
+
+        senderKeyInfoJson STRING
+      , deletedAtTimestamp INTEGER, allowsReplies INTEGER, isBlockList INTEGER, storageID STRING, storageVersion INTEGER, storageUnknownFields BLOB, storageNeedsSync INTEGER);
+CREATE TABLE storyDistributionMembers(
+        listId STRING NOT NULL REFERENCES storyDistributions(id)
+          ON DELETE CASCADE
+          ON UPDATE CASCADE,
+        serviceId STRING NOT NULL,
+
+        PRIMARY KEY (listId, serviceId)
+      );
+CREATE TABLE uninstalled_sticker_packs (
+        id STRING NOT NULL PRIMARY KEY,
+        uninstalledAt NUMBER NOT NULL,
+        storageID STRING,
+        storageVersion NUMBER,
+        storageUnknownFields BLOB,
+        storageNeedsSync INTEGER NOT NULL
+      );
+CREATE TABLE groupCallRingCancellations(
+        ringId INTEGER PRIMARY KEY,
+        createdAt INTEGER NOT NULL
+      );
+CREATE TABLE IF NOT EXISTS &#39;messages_fts_data&#39;(id INTEGER PRIMARY KEY, block BLOB);
+CREATE TABLE IF NOT EXISTS &#39;messages_fts_idx&#39;(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
+CREATE TABLE IF NOT EXISTS &#39;messages_fts_content&#39;(id INTEGER PRIMARY KEY, c0);
+CREATE TABLE IF NOT EXISTS &#39;messages_fts_docsize&#39;(id INTEGER PRIMARY KEY, sz BLOB);
+CREATE TABLE IF NOT EXISTS &#39;messages_fts_config&#39;(k PRIMARY KEY, v) WITHOUT ROWID;
+CREATE TABLE edited_messages(
+        messageId STRING REFERENCES messages(id)
+          ON DELETE CASCADE,
+        sentAt INTEGER,
+        readStatus INTEGER
+      , conversationId STRING);
+CREATE TABLE mentions (
+        messageId REFERENCES messages(id) ON DELETE CASCADE,
+        mentionAci STRING,
+        start INTEGER,
+        length INTEGER
+      );
+CREATE TABLE kyberPreKeys(
+        id STRING PRIMARY KEY NOT NULL,
+        json TEXT NOT NULL, ourServiceId NUMBER
+        GENERATED ALWAYS AS (json_extract(json, &#39;$.ourServiceId&#39;)));
+CREATE TABLE callsHistory (
+        callId TEXT PRIMARY KEY,
+        peerId TEXT NOT NULL, -- conversation id (legacy) | uuid | groupId | roomId
+        ringerId TEXT DEFAULT NULL, -- ringer uuid
+        mode TEXT NOT NULL, -- enum &quot;Direct&quot; | &quot;Group&quot;
+        type TEXT NOT NULL, -- enum &quot;Audio&quot; | &quot;Video&quot; | &quot;Group&quot;
+        direction TEXT NOT NULL, -- enum &quot;Incoming&quot; | &quot;Outgoing
+        -- Direct: enum &quot;Pending&quot; | &quot;Missed&quot; | &quot;Accepted&quot; | &quot;Deleted&quot;
+        -- Group: enum &quot;GenericGroupCall&quot; | &quot;OutgoingRing&quot; | &quot;Ringing&quot; | &quot;Joined&quot; | &quot;Missed&quot; | &quot;Declined&quot; | &quot;Accepted&quot; | &quot;Deleted&quot;
+        status TEXT NOT NULL,
+        timestamp INTEGER NOT NULL,
+        UNIQUE (callId, peerId) ON CONFLICT FAIL
+      );
+[ dropped all indexes to save space in this blog post ]
+CREATE TRIGGER messages_on_view_once_update AFTER UPDATE ON messages
+      WHEN
+        new.body IS NOT NULL AND new.isViewOnce = 1
+      BEGIN
+        DELETE FROM messages_fts WHERE rowid = old.rowid;
+      END;
+CREATE TRIGGER messages_on_insert AFTER INSERT ON messages
+      WHEN new.isViewOnce IS NOT 1 AND new.storyId IS NULL
+      BEGIN
+        INSERT INTO messages_fts
+          (rowid, body)
+        VALUES
+          (new.rowid, new.body);
+      END;
+CREATE TRIGGER messages_on_delete AFTER DELETE ON messages BEGIN
+        DELETE FROM messages_fts WHERE rowid = old.rowid;
+        DELETE FROM sendLogPayloads WHERE id IN (
+          SELECT payloadId FROM sendLogMessageIds
+          WHERE messageId = old.id
+        );
+        DELETE FROM reactions WHERE rowid IN (
+          SELECT rowid FROM reactions
+          WHERE messageId = old.id
+        );
+        DELETE FROM storyReads WHERE storyId = old.storyId;
+      END;
+CREATE VIRTUAL TABLE messages_fts USING fts5(
+        body,
+        tokenize = &#39;signal_tokenizer&#39;
+      );
+CREATE TRIGGER messages_on_update AFTER UPDATE ON messages
+      WHEN
+        (new.body IS NULL OR old.body IS NOT new.body) AND
+         new.isViewOnce IS NOT 1 AND new.storyId IS NULL
+      BEGIN
+        DELETE FROM messages_fts WHERE rowid = old.rowid;
+        INSERT INTO messages_fts
+          (rowid, body)
+        VALUES
+          (new.rowid, new.body);
+      END;
+CREATE TRIGGER messages_on_insert_insert_mentions AFTER INSERT ON messages
+      BEGIN
+        INSERT INTO mentions (messageId, mentionAci, start, length)
+        
+    SELECT messages.id, bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; as mentionAci,
+      bodyRanges.value -&gt;&gt; &#39;start&#39; as start,
+      bodyRanges.value -&gt;&gt; &#39;length&#39; as length
+    FROM messages, json_each(messages.json -&gt;&gt; &#39;bodyRanges&#39;) as bodyRanges
+    WHERE bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; IS NOT NULL
+  
+        AND messages.id = new.id;
+      END;
+CREATE TRIGGER messages_on_update_update_mentions AFTER UPDATE ON messages
+      BEGIN
+        DELETE FROM mentions WHERE messageId = new.id;
+        INSERT INTO mentions (messageId, mentionAci, start, length)
+        
+    SELECT messages.id, bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; as mentionAci,
+      bodyRanges.value -&gt;&gt; &#39;start&#39; as start,
+      bodyRanges.value -&gt;&gt; &#39;length&#39; as length
+    FROM messages, json_each(messages.json -&gt;&gt; &#39;bodyRanges&#39;) as bodyRanges
+    WHERE bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; IS NOT NULL
+  
+        AND messages.id = new.id;
+      END;
+sqlite&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;Finally I have the tool needed to inspect and process Signal
+messages that I need, without using the vendor provided client.  Now
+on to transforming it to a more useful format.&lt;/p&gt;
+
+&lt;p&gt;As usual, if you use Bitcoin and want to show your support of my
+activities, please send Bitcoin donations to my address
+&lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;
+</description>
+       </item>
+       
        <item>
                <title>New chrpath release 0.17</title>
-               <link>https://people.skolelinux.org/pere/blog/New_chrpath_release_0_17.html</link>        
-               <guid isPermaLink="true">https://people.skolelinux.org/pere/blog/New_chrpath_release_0_17.html</guid>
+               <link>http://www.hungry.com/~pere/blog/New_chrpath_release_0_17.html</link>        
+               <guid isPermaLink="true">http://www.hungry.com/~pere/blog/New_chrpath_release_0_17.html</guid>
                 <pubDate>Fri, 10 Nov 2023 07:30:00 +0100</pubDate>
-               <description>&lt;p&gt;The chrpath package provide a simple command line tool to remove
-the rpath or runpath of compiled ELF program.  It is almost 10 years
-since I updated the code base, but I stumbled over the tool today, and
-decided it was time to move the code base from Subversion to git and
-find a new home for it, as the previous one (Debian Alioth) has been
-shut down.  I decided to go with
+               <description>&lt;p&gt;The chrpath package provide a simple command line tool to remove or
+modify the rpath or runpath of compiled ELF program.  It is almost 10
+years since I updated the code base, but I stumbled over the tool
+today, and decided it was time to move the code base from Subversion
+to git and find a new home for it, as the previous one (Debian Alioth)
+has been shut down.  I decided to go with
 &lt;a href=&quot;https://codeberg.org/&quot;&gt;Codeberg&lt;/a&gt; this time, as it is my git
 service of choice these days, did a quick and dirty migration to git
 and updated the code with a few patches I found in the Debian bug
@@ -44,8 +1078,8 @@ activities, please send Bitcoin donations to my address
        
        <item>
                <title>Test framework for DocBook processors / formatters</title>
-               <link>https://people.skolelinux.org/pere/blog/Test_framework_for_DocBook_processors___formatters.html</link>        
-               <guid isPermaLink="true">https://people.skolelinux.org/pere/blog/Test_framework_for_DocBook_processors___formatters.html</guid>
+               <link>http://www.hungry.com/~pere/blog/Test_framework_for_DocBook_processors___formatters.html</link>        
+               <guid isPermaLink="true">http://www.hungry.com/~pere/blog/Test_framework_for_DocBook_processors___formatters.html</guid>
                 <pubDate>Sun, 5 Nov 2023 13:00:00 +0100</pubDate>
                <description>&lt;p&gt;All the books I have published so far has been using
 &lt;a href=&quot;https://docbook.org/&quot;&gt;DocBook&lt;/a&gt; somewhere in the process.