]> pere.pagekite.me Git - homepage.git/blobdiff - blog/archive/2023/11/11.rss
Nytt bokforslag.
[homepage.git] / blog / archive / 2023 / 11 / 11.rss
index b33cf96ebff2d0106fe0939c4cb5a63062c49d01..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>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 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
+tracker.  These are the release notes:&lt;/p&gt;
+
+&lt;p&gt;New in 0.17 released 2023-11-10:&lt;/p&gt;
+
+&lt;ul&gt;
+&lt;li&gt;Moved project to Codeberg, as Alioth is shut down.&lt;/li&gt;
+&lt;li&gt;Add Solaris support (use &amp;lt;sys/byteorder.h&gt; instead of &amp;lt;byteswap.h&gt;).
+   Patch from Rainer Orth.&lt;/li&gt;
+&lt;li&gt;Added missing newline from printf() line.  Patch from Frank Dana.&lt;/li&gt;
+&lt;li&gt;Corrected handling of multiple ELF sections. Patch from Frank Dana.&lt;/li&gt;
+&lt;li&gt;Updated build rules for .deb.  Partly based on patch from djcj.&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;p&gt;The latest edition is tagged and available from
+&lt;a href=&quot;https://codeberg.org/pere/chrpath&quot;&gt;https://codeberg.org/pere/chrpath&lt;/a&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>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.
@@ -21,12 +1091,15 @@ paper production or for Internet consumption.  This is made possible
 with a wide variety of free software tools with DocBook support in
 Debian.  The source format of later books have been docx via rst,
 Markdown, Filemaker and Asciidoc, and for all of these I was able to
-generate a suitable DocBook file for further processing using pandoc,
-a2x and asciidoctor, as well as rendering using
+generate a suitable DocBook file for further processing using
+&lt;a href=&quot;https://tracker.debian.org/pkg/pandoc&quot;&gt;pandoc&lt;/a&gt;,
+&lt;a href=&quot;https://tracker.debian.org/pkg/asciidoc&quot;&gt;a2x&lt;/a&gt; and
+&lt;a href=&quot;https://tracker.debian.org/pkg/asciidoctor&quot;&gt;asciidoctor&lt;/a&gt;,
+as well as rendering using
 &lt;a href=&quot;https://tracker.debian.org/pkg/xmlto&quot;&gt;xmlto&lt;/a&gt;,
 &lt;a href=&quot;https://tracker.debian.org/pkg/dbtoepub&quot;&gt;dbtoepub&lt;/a&gt;,
 &lt;a href=&quot;https://tracker.debian.org/pkg/dblatex&quot;&gt;dblatex&lt;/a&gt;,
-&lt;a href=&quot;https://tracker.debian.org/pkg/dblatex&quot;&gt;docbook-xsl&lt;/a&gt; and
+&lt;a href=&quot;https://tracker.debian.org/pkg/docbook-xsl&quot;&gt;docbook-xsl&lt;/a&gt; and
 &lt;a href=&quot;https://tracker.debian.org/pkg/fop&quot;&gt;fop&lt;/a&gt;.&lt;/p&gt;
 
 &lt;p&gt;Most of the &lt;a href=&quot;http://www.hungry.com/~pere/publisher/&quot;&gt;books I
@@ -63,7 +1136,7 @@ web pages at
 &lt;a href=&quot;https://pere.codeberg.page/docbook-example/&quot;&gt;https://pere.codeberg.page/docbook-example/&lt;/a&gt;.
 Using this test framework I have been able to discover and report
 several bugs and missing features in various tools, and got a lot of
-them fixed.  For example I got Northern Sami keywoards added to both
+them fixed.  For example I got Northern Sami keywords added to both
 docbook-xsl and dblatex, fixed several typos in Norwegian bokmål and
 Norwegian Nynorsk, support for non-ascii title IDs added to pandoc,
 Norwegian index sorting support fixed in xindy and initial Norwegian