Comando para recuperar la lista de caracteres en una clase de personaje determinada en la configuración regional actual

Comando para recuperar la lista de caracteres en una clase de personaje determinada en la configuración regional actual

¿Cuál podría ser una forma de recuperar una lista de todos los caracteres en una clase de caracteres determinada (como ,, blank... ) en la ubicación actual?alphadigit

Por ejemplo,

LC_ALL=en_GB.UTF-8 that-command blank

Lo ideal sería que en mi sistema Debian mostrara algo como:

      09 U+0009 HORIZONTAL TAB
      20 U+0020 SPACE
e1 9a 80 U+1680 OGHAM SPACE MARK
e1 a0 8e U+180E MONGOLIAN VOWEL SEPARATOR
e2 80 80 U+2000 EN QUAD
e2 80 81 U+2001 EM QUAD
e2 80 82 U+2002 EN SPACE
e2 80 83 U+2003 EM SPACE
e2 80 84 U+2004 THREE-PER-EM SPACE
e2 80 85 U+2005 FOUR-PER-EM SPACE
e2 80 86 U+2006 SIX-PER-EM SPACE
e2 80 88 U+2008 PUNCTUATION SPACE
e2 80 89 U+2009 THIN SPACE
e2 80 8a U+200A HAIR SPACE
e2 81 9f U+205F MEDIUM MATHEMATICAL SPACE
e3 80 80 U+3000 IDEOGRAPHIC SPACE

Y en la configuración regional C podría mostrarse algo como:

09 U+0009 HORIZONTAL TAB
20 U+0020 SPACE

Es decir, la representación del carácter en la configuración regional en términos de matrices de bytes (como UTF-8 en el primer ejemplo y un solo byte en el segundo), el punto de código del carácter Unicode equivalente y una descripción.

Contexto

(editar) Ahora que la vulnerabilidad ha sido parcheada y divulgada hace mucho tiempo, puedo agregar un poco de contexto.

Hice esa pregunta en el momento en que estaba investigando.CVE 2014-0475. glibctenía un error que permitía al usuario usar configuraciones regionales como LC_ALL=../../../../tmp/evil-localelas que se resuelven en relación con la ruta de búsqueda de configuración regional estándar del sistema y, por lo tanto, permiten usar cualquier archivo como definición de configuración regional.

Podría crear una ubicación deshonestapor ejemplo, con un solo byte por conjunto de caracteres donde se consideraron la mayoría de los caracteres, excepto s, hy algunos otrosespacios en blancoy eso haría que bashse ejecute shmientras se analiza un archivo Debian típico /etc/bash.bashrc(y eso podría usarse para obtener acceso al shell en un gitservidor de alojamiento, por ejemplo, siempre que bashse use como el shell de inicio de sesión del gitusuario del servidor y que el sshservidor acepte LC_*/ LANGvariables y que el atacante pueda subir archivos al servidor).

Ahora, si alguna vez encuentro una LC_CTYPE(definición regional compilada) en /tmp/evil, ¿cómo puedo saber que es falsa y de qué manera?

Entonces, mi objetivo es descompilar esas definiciones locales y, si no, al menos saber qué caracteres (junto con su codificación) están en una clase de caracteres determinada.

Así que con eso en mente:

  • Las soluciones que analizan los archivos fuente de la configuración regional (las definiciones de configuración regional como las de /usr/share/i18n/localeDebian) no sirven de nada en mi caso.
  • Las propiedades de los caracteres Unicode son irrelevantes. Sólo me importa lo que dice el lugar. En un sistema Debian, incluso entre dos configuraciones regionales del sistema UTF-8, y mucho menos entre dos configuraciones regionales no autorizadas, la lista de caracteres en una clase puede ser diferente.
  • Herramientas como recode, pythono perlque realizan la conversión de bytes/multibytes a/desde caracteres no se pueden usar ya que pueden (y en la práctica lo hacen) realizar la conversión de una manera diferente a la configuración regional.

Respuesta1

POSIBLE SOLUCIÓN FINAL

Así que tomé toda la información a continuación y se me ocurrió esto:

for class in $(
    locale -v LC_CTYPE | 
    sed 's/combin.*//;s/;/\n/g;q'
) ; do 
    printf "\n\t%s\n\n" $class
    recode u2/test16 -q </dev/null | 
    tr -dc "[:$class:]" | 
    od -A n -t a -t o1z -w12
done

NOTA:

Lo uso odcomo filtro final arriba por preferencia y porque sé que no trabajaré con caracteres multibyte, que no manejará correctamente. recode u2..dumpgenerará un resultado más parecido al especificado en la pregunta y manejará los caracteres anchos correctamente.

PRODUCCIÓN

        upper

   A   B   C   D   E   F   G   H   I   J   K   L
 101 102 103 104 105 106 107 110 111 112 113 114  >ABCDEFGHIJKL<
   M   N   O   P   Q   R   S   T   U   V   W   X
 115 116 117 120 121 122 123 124 125 126 127 130  >MNOPQRSTUVWX<
   Y   Z
 131 132                                          >YZ<

        lower

   a   b   c   d   e   f   g   h   i   j   k   l
 141 142 143 144 145 146 147 150 151 152 153 154  >abcdefghijkl<
   m   n   o   p   q   r   s   t   u   v   w   x
 155 156 157 160 161 162 163 164 165 166 167 170  >mnopqrstuvwx<
   y   z
 171 172                                          >yz<

        alpha

   A   B   C   D   E   F   G   H   I   J   K   L
 101 102 103 104 105 106 107 110 111 112 113 114  >ABCDEFGHIJKL<
   M   N   O   P   Q   R   S   T   U   V   W   X
 115 116 117 120 121 122 123 124 125 126 127 130  >MNOPQRSTUVWX<
   Y   Z   a   b   c   d   e   f   g   h   i   j
 131 132 141 142 143 144 145 146 147 150 151 152  >YZabcdefghij<
   k   l   m   n   o   p   q   r   s   t   u   v
 153 154 155 156 157 160 161 162 163 164 165 166  >klmnopqrstuv<
   w   x   y   z
 167 170 171 172                                  >wxyz<

        digit

   0   1   2   3   4   5   6   7   8   9
 060 061 062 063 064 065 066 067 070 071          >0123456789<

       xdigit                                                                                          

   0   1   2   3   4   5   6   7   8   9   A   B
 060 061 062 063 064 065 066 067 070 071 101 102  >0123456789AB<
   C   D   E   F   a   b   c   d   e   f
 103 104 105 106 141 142 143 144 145 146          >CDEFabcdef<

        space

  ht  nl  vt  ff  cr  sp
 011 012 013 014 015 040                          >..... <

        print

  sp   !   "   #   $   %   &   '   (   )   *   +
 040 041 042 043 044 045 046 047 050 051 052 053  > !"#$%&'()*+<
   ,   -   .   /   0   1   2   3   4   5   6   7
 054 055 056 057 060 061 062 063 064 065 066 067  >,-./01234567<
   8   9   :   ;   <   =   >   ?   @   A   B   C
 070 071 072 073 074 075 076 077 100 101 102 103  >89:;<=>?@ABC<
   D   E   F   G   H   I   J   K   L   M   N   O
 104 105 106 107 110 111 112 113 114 115 116 117  >DEFGHIJKLMNO<
   P   Q   R   S   T   U   V   W   X   Y   Z   [
 120 121 122 123 124 125 126 127 130 131 132 133  >PQRSTUVWXYZ[<
   \   ]   ^   _   `   a   b   c   d   e   f   g
 134 135 136 137 140 141 142 143 144 145 146 147  >\]^_`abcdefg<
   h   i   j   k   l   m   n   o   p   q   r   s
 150 151 152 153 154 155 156 157 160 161 162 163  >hijklmnopqrs<
   t   u   v   w   x   y   z   {   |   }   ~
 164 165 166 167 170 171 172 173 174 175 176      >tuvwxyz{|}~<

        graph

   !   "   #   $   %   &   '   (   )   *   +   ,
 041 042 043 044 045 046 047 050 051 052 053 054  >!"#$%&'()*+,<
   -   .   /   0   1   2   3   4   5   6   7   8
 055 056 057 060 061 062 063 064 065 066 067 070  >-./012345678<
   9   :   ;   <   =   >   ?   @   A   B   C   D
 071 072 073 074 075 076 077 100 101 102 103 104  >9:;<=>?@ABCD<
   E   F   G   H   I   J   K   L   M   N   O   P
 105 106 107 110 111 112 113 114 115 116 117 120  >EFGHIJKLMNOP<
   Q   R   S   T   U   V   W   X   Y   Z   [   \
 121 122 123 124 125 126 127 130 131 132 133 134  >QRSTUVWXYZ[\<
   ]   ^   _   `   a   b   c   d   e   f   g   h
 135 136 137 140 141 142 143 144 145 146 147 150  >]^_`abcdefgh<
   i   j   k   l   m   n   o   p   q   r   s   t
 151 152 153 154 155 156 157 160 161 162 163 164  >ijklmnopqrst<
   u   v   w   x   y   z   {   |   }   ~
 165 166 167 170 171 172 173 174 175 176          >uvwxyz{|}~<

        blank

  ht  sp
 011 040                                          >. <

        cntrl

 nul soh stx etx eot enq ack bel  bs  ht  nl  vt
 000 001 002 003 004 005 006 007 010 011 012 013  >............<
  ff  cr  so  si dle dc1 dc2 dc3 dc4 nak syn etb
 014 015 016 017 020 021 022 023 024 025 026 027  >............<
 can  em sub esc  fs  gs  rs  us del
 030 031 032 033 034 035 036 037 177              >.........<

        punct

   !   "   #   $   %   &   '   (   )   *   +   ,
 041 042 043 044 045 046 047 050 051 052 053 054  >!"#$%&'()*+,<
   -   .   /   :   ;   <   =   >   ?   @   [   \
 055 056 057 072 073 074 075 076 077 100 133 134  >-./:;<=>?@[\<
   ]   ^   _   `   {   |   }   ~
 135 136 137 140 173 174 175 176                  >]^_`{|}~<

        alnum

   0   1   2   3   4   5   6   7   8   9   A   B
 060 061 062 063 064 065 066 067 070 071 101 102  >0123456789AB<
   C   D   E   F   G   H   I   J   K   L   M   N
 103 104 105 106 107 110 111 112 113 114 115 116  >CDEFGHIJKLMN<
   O   P   Q   R   S   T   U   V   W   X   Y   Z
 117 120 121 122 123 124 125 126 127 130 131 132  >OPQRSTUVWXYZ<
   a   b   c   d   e   f   g   h   i   j   k   l
 141 142 143 144 145 146 147 150 151 152 153 154  >abcdefghijkl<
   m   n   o   p   q   r   s   t   u   v   w   x
 155 156 157 160 161 162 163 164 165 166 167 170  >mnopqrstuvwx<
   y   z

API DEL PROGRAMADOR

Como lo demuestro a continuación, recodele proporcionaré su mapa de personajes completo. Según su manual, esto lo hace primero según el valor actual de la DEFAULT_CHARSETvariable de entorno, o en su defecto,funciona exactamente como usted especifica:

Cuando unjuego de caracteresEl nombre se omite o se deja vacío, DEFAULT_CHARSETen su lugar se utiliza el valor de la variable en el entorno. Si esta variable no está definida, la recodebiblioteca utiliza lacodificación de la configuración regional actual.EnPOSIXsistemas compatibles, esto depende del primer valor no vacío entre las variables de entorno LC_ALL, LC_CTYPE, LANGy se puede determinar mediante el comandolocale charmap.

También vale la pena señalar recodequees una API:

El programa nombrado recodees sólo una aplicación de su biblioteca de grabación. La biblioteca de grabación está disponible por separado para otros programas en C. Una buena forma de familiarizarse con la biblioteca de grabación es familiarizarse con el recodeprograma en sí.

Para utilizar la biblioteca de grabación una vez instalada, un programa en C debe tener una línea:

#include <recode.h>

Para una comparación de cadenas amigable a nivel internacional Los estándares POSIXy Cdefinen elstrcoll()función:

La strcoll()función comparará la cadena señalada por s1con la cadena señalada por s2, ambas interpretadas como apropiadas para la categoría LC_COLLATE de la configuración regional actual.

La strcoll()función no cambiará la configuración de errno si tiene éxito.

Dado que no se reserva ningún valor de retorno para indicar un error, una aplicación que desee verificar situaciones de error debe establecer errno en 0, luego llamar strcoll()y luego verificar errno.

Aquí hay unubicado por separadoejemplo de su uso:

#include <stdio.h>
#include <string.h>

int main ()
{
   char str1[15];
   char str2[15];
   int ret;


   strcpy(str1, "abc");
   strcpy(str2, "ABC");

   ret = strcoll(str1, str2);

   if(ret > 0)
   {
      printf("str1 is less than str2");
   }
   else if(ret < 0) 
   {
      printf("str2 is less than str1");
   }
   else 
   {
      printf("str1 is equal to str2");
   }

   return(0);
}

Con respecto a las POSIXclases de personajes, ya habrás notado que usaste la CAPI para encontrarlas. Para caracteres y clases Unicode puedes usarrecode's volcado-con-nombresconjunto de caracteres para obtener el resultado deseado. De sumanual de nuevo:

Por ejemplo, el comando recode l2..full < inputimplica una conversión necesaria delatín-2aUCS-2,comovolcado-con-nombressólo está conectado desdeUCS-2.En tales casos, recodeno muestra el original. latín-2códigos en el volcado, solo los correspondientesUCS-2valores. Para dar un ejemplo más simple, el comando

 echo 'Hello, world!' | recode us..dump

produce el siguiente resultado:

UCS2   Mne   Description

0048   H     latin capital letter h 
0065   e     latin small letter e
006C   l     latin small letter l 
006C   l     latin small letter l
006F   o     latin small letter o 
002C   ,     comma 
0020  SP     space 
0077   w     latin small letter w 
006F   o     latin small letter o 
0072   r     latin small letter r 
006C   l     latin small letter l 
0064   d     latin small letter d 
0021   !     exclamation mark 
000A   LF    line feed (lf)

El comentario descriptivo se proporciona en inglés y ASCII, pero si la descripción en inglés no está disponible pero sí una en francés, entonces se proporciona la descripción en francés, utilizando Latin-1. Sin embargo, si la variable de entorno LANGUAGEo LANGcomienza con las letrasfr, la preferencia de listado pasa al francés cuando ambas descripciones están disponibles.

Usando una sintaxis similar a la anterior combinada con suconjunto de datos de prueba incluidoPuedo obtener mi propio mapa de personajes con:

recode -q u8/test8..dump </dev/null

PRODUCCIÓN

UCS2   Mne   Description

0001   SH    start of heading (soh)
0002   SX    start of text (stx)
0003   EX    end of text (etx)    
...
002B   +     plus sign
002C   ,     comma
002D   -     hyphen-minus
...
0043   C     latin capital letter c
0044   D     latin capital letter d
0045   E     latin capital letter e
...
006B   k     latin small letter k
006C   l     latin small letter l
006D   m     latin small letter m
...
007B   (!    left curly bracket
007C   !!    vertical line
007D   !)    right curly bracket
007E   '?    tilde
007F   DT    delete (del)

Pero para personajes comunes, recodeaparentemente no es necesario. Esto debería proporcionarle caracteres con nombre para todo el conjunto de caracteres de 128 bytes:

printf %b "$(printf \\%04o $(seq 128))" | 
luit -c |
od -A n -t o1z -t a -w12

PRODUCCIÓN

 001 002 003 004 005 006 007 010 011 012 013 014  >............<
 soh stx etx eot enq ack bel  bs  ht  nl  vt  ff
...
 171 172 173 174 175 176 177                      >yz{|}~.<
   y   z   {   |   }   ~ del

Por supuesto, sólo se representan 128 bytes, pero eso se debe a que mi configuración regional,utf-8charmaps o no, utiliza elASCIIconjunto de caracteres y nada más. Entonces eso es todo lo que tengo. Sin embargo, si lo ejecutara sin luitfiltrarlo, odlo revertiría e imprimiría el mismo mapa nuevamente hasta\0400.

Sin embargo, existen dos problemas importantes con el método anterior. En primer lugar, está el orden de clasificación del sistema: para configuraciones regionales que no son ASCII, los valores de bits para los conjuntos de caracteres no son simplemente una influencia seq, lo cual, como creo, es probablemente el núcleo del problema que estás tratando de resolver.

Bueno, tr's manla página de GNU afirma que ampliará las [:upper:] [:lower:]clases en orden, pero eso no es mucho.

Me imagino que se podría implementar alguna solución dura, sortpero sería una herramienta bastante difícil de manejar para una API de programación backend.

recodeHaré esto correctamente, pero el otro día no parecías muy enamorado del programa. Quizás las ediciones de hoy arrojen una luz más amigable sobre esto o quizás no.

GNU también ofrece la gettextbiblioteca de funciones y parece ser capaz deabordar este problemaal menos por el LC_MESSAGEScontexto:

- Función: char * bind_textdomain_codeset( const char *domainname, const char *codeset)

La bind_textdomain_codesetfunción se puede utilizar para especificar el juego de caracteres de salida para catálogos de mensajes para el dominio. nombre de dominio. Elconjunto de códigosEl argumento debe ser válido.conjunto de códigosnombre que se puede utilizar para eliconov_abiertofunción o un puntero nulo.

Si elconjunto de códigosEl parámetro es el puntero nulo, bind_textdomain_codeset devuelve el valor seleccionado actualmente.conjunto de códigospara el dominio con el nombre nombre de dominio. Devuelve NULL si noconjunto de códigosaún no ha sido seleccionado.

La bind_textdomain_codesetfunción se puede utilizar varias veces. Si se usa varias veces con el mismo argumento de nombre de dominio, la llamada posterior anula la configuración realizada por la anterior.

La bind_textdomain_codesetfunción devuelve un puntero a una cadena que contiene el nombre del conjunto de códigos seleccionado. La cadena se asigna internamente en la función y el usuario no debe cambiarla. Si el sistema se quedó sin núcleo durante la ejecución de bind_textdomain_codeset, el valor de retorno es NULL y la variable global errno se establece en consecuencia.

También puedes usar nativoCarácter Unicodecategorias, que son independientes del lenguaje y renuncian por completo a las clases POSIX, o tal vez para solicitar a las primeras que le proporcionen suficiente información para definir las segundas.

Además de las complicaciones, Unicode también ofrece nuevas posibilidades. Una es que cada carácter Unicode pertenece a un determinadocategoría.Puedes hacer coincidir un solo carácter perteneciente a la categoría "letra" con \p{L}. Puedes hacer coincidir un solo carácter que no pertenezca a esa categoría con \P{L}.

Nuevamente, "carácter" realmente significa "punto de código Unicode". \p{L}coincide con un único punto de código en la categoría "letra". Si su cadena de entrada está à codificada como U+0061 U+0300, coincide asin acento. Si la entrada está àcodificada como U+00E0, coincide àcon el acento. La razón es que tanto el código apunta U+0061 (a)como U+00E0 (à)está en la categoría “letra”, mientras que U+0300está en la categoría “marca”.

Ahora deberías entender por qué \P{M}\p{M}*+es el equivalente a \X. \P{M}coincide con un punto de código que no es una marca de combinación, mientras que \p{M}*+ coincide con cero o más puntos de código que son marcas de combinación. Para hacer coincidir una letra que incluya signos diacríticos, utilice \p{L}\p{M}*+. Esta última expresión regular siempre coincidirá con à, independientemente de cómo esté codificada. El cuantificador posesivo se asegura de que retroceder no haga \P{M}\p{M}*+coincidir una no marca sin las marcas combinadas que la siguen, lo que \X nunca sucedería.

El mismo sitio web que proporcionó la información anterior también analizaTclpropioPOSIX-obedienteimplementación de expresiones regulares que podría ser otra forma más de lograr su objetivo.

Y la última de las soluciones, le sugeriré que pueda consultar el LC_COLLATEarchivo en sí para obtener la información completa yen ordenmapa de caracteres del sistema. Puede que esto no parezca fácil de hacer, pero logré cierto éxito con lo siguiente después de compilarlo localedefcomo se muestra a continuación:

<LC_COLLATE od -j2K -a -w2048 -v  | 
tail -n2 | 
cut -d' ' -f$(seq -s',' 4 2 2048) | 
sed 's/nul\|\\0//g;s/  */ /g;:s;
    s/\([^ ]\{1,3\}\) \1/\1/;ts;
    s/\(\([^ ][^ ]*  *\)\{16\}\)/\1\n/g'

 dc1 dc2 dc3 dc4 nak syn etb can c fs c rs c sp ! "
# $ % & ' ( ) * + , - . / 0 1 2
3 4 5 6 7 8 9 : ; < = > ? @ A B
C D E F G H I J K L M N O P Q R
S T U V W X Y Z [ \ ] ^ _ ` a b
c d e f g h i j k l m n o p q r
s t u v w x y z { | } ~ del soh stx etx
eot enq ack bel c ht c vt cr c si dle dc1 del

Es cierto que actualmente tiene fallas, pero espero que al menos demuestre la posibilidad.

AL PRIMER RUBOR

strings $_/en_GB

#OUTPUT

int_select "<U0030><U0030>"
...
END LC_TELEPHONE

Realmente no parecía mucho, pero luego comencé a notar copycomandos en toda la lista. El archivo anterior parece copyestar en"en_US"por ejemplo, y otro muy importante que parece que todos comparten hasta cierto punto es iso_14651_t1_common.

Es bastante grande:

strings $_ | wc -c

#OUTPUT
431545

Aquí está la introducción a /usr/share/i18n/locales/POSIX:

# Territory:
# Revision: 1.1
# Date: 1997-03-15
# Application: general
# Users: general
# Repertoiremap: POSIX
# Charset: ISO646:1993
# Distribution and use is free, also for
# commercial purposes.
LC_CTYPE
# The following is the POSIX Locale LC_CTYPE.
# "alpha" is by default "upper" and "lower"
# "alnum" is by definiton "alpha" and "digit"
# "print" is by default "alnum", "punct" and the <U0020> character
# "graph" is by default "alnum" and "punct"
upper   <U0041>;<U0042>;<U0043>;<U0044>;<U0045>;<U0046>;<U0047>;<U0048>;\
        <U0049>;<U004A>;<U004B>;<U004C>;<U004D>;<U004E>;<U004F>;

...

Por supuesto, puedes grepsuperar esto, pero podrías simplemente:

recode -lf gb

En cambio. Obtendrías algo como esto:

Dec  Oct Hex   UCS2  Mne  BS_4730

  0  000  00   0000  NU   null (nul)
  1  001  01   0001  SH   start of heading (soh)
...

... Y MÁS

También hay un dispositivo de traducción luitterminal UTF-8, ptysupongo que actúa como intermediario para XTerms sin soporte UTF-8. Maneja muchos cambios, como registrar todos los bytes convertidos en un archivo o como un filtro -csimple .|pipe

Nunca me di cuenta de que había tanto en esto: las ubicaciones, los mapas de personajes y todo eso. Esto aparentemente es muyVaya cosapero supongo que todo sucede detrás de escena. Hay, al menos en mi sistema, un par de cientos man 3de resultados relacionados para búsquedas relacionadas con la configuración regional.

Y también hay:

zcat /usr/share/i18n/charmaps/UTF-8*gz | less

    CHARMAP
<U0000>     /x00         NULL
<U0001>     /x01         START OF HEADING
<U0002>     /x02         START OF TEXT
<U0003>     /x03         END OF TEXT
<U0004>     /x04         END OF TRANSMISSION
<U0005>     /x05         ENQUIRY
...

Eso continuará por unmuyhace mucho.

Las Xlibfunciones manejan esto todo el tiempo; luites parte de ese paquete.

Las Tcl_uni...funciones también podrían resultar útiles.

Solo un poco <tab>de finalización y manbúsquedas y he aprendido bastante sobre este tema.

Con localedef- puedes compilar el localesen tu I18Ndirectorio. El resultado es original y no es extraordinariamente útil, no se parece en charmapsnada a él, pero puedes obtener el formato sin formato tal como lo especificaste anteriormente, como lo hice yo:

mkdir -p dir && cd $_ ; localedef -f UTF-8 -i en_GB ./ 

ls -l
total 1508
drwxr-xr-x 1 mikeserv mikeserv      30 May  6 18:35 LC_MESSAGES
-rw-r--r-- 1 mikeserv mikeserv     146 May  6 18:35 LC_ADDRESS
-rw-r--r-- 1 mikeserv mikeserv 1243766 May  6 18:35 LC_COLLATE
-rw-r--r-- 1 mikeserv mikeserv  256420 May  6 18:35 LC_CTYPE
-rw-r--r-- 1 mikeserv mikeserv     376 May  6 18:35 LC_IDENTIFICATION
-rw-r--r-- 1 mikeserv mikeserv      23 May  6 18:35 LC_MEASUREMENT
-rw-r--r-- 1 mikeserv mikeserv     290 May  6 18:35 LC_MONETARY
-rw-r--r-- 1 mikeserv mikeserv      77 May  6 18:35 LC_NAME
-rw-r--r-- 1 mikeserv mikeserv      54 May  6 18:35 LC_NUMERIC
-rw-r--r-- 1 mikeserv mikeserv      34 May  6 18:35 LC_PAPER
-rw-r--r-- 1 mikeserv mikeserv      56 May  6 18:35 LC_TELEPHONE
-rw-r--r-- 1 mikeserv mikeserv    2470 May  6 18:35 LC_TIME

Luego odpuedes leerlo: bytes y cadenas:

od -An -a -t u1z -w12 LC_COLLATE | less

 etb dle enq  sp dc3 nul nul nul   T nul nul nul
  23  16   5  32  19   0   0   0  84   0   0   0  >... ....T...<
...

Aunque está muy lejos de ganar un concurso de belleza, ese es un resultado utilizable. Y od, por supuesto, también es tan configurable como quieras.

Supongo que también me olvidé de estos:

    perl -mLocale                                                                                       

 -- Perl module --
Locale::Codes                    Locale::Codes::LangFam           Locale::Codes::Script_Retired
Locale::Codes::Constants         Locale::Codes::LangFam_Codes     Locale::Country
Locale::Codes::Country           Locale::Codes::LangFam_Retired   Locale::Currency
Locale::Codes::Country_Codes     Locale::Codes::LangVar           Locale::Language
Locale::Codes::Country_Retired   Locale::Codes::LangVar_Codes     Locale::Maketext
Locale::Codes::Currency          Locale::Codes::LangVar_Retired   Locale::Maketext::Guts
Locale::Codes::Currency_Codes    Locale::Codes::Language          Locale::Maketext::GutsLoader
Locale::Codes::Currency_Retired  Locale::Codes::Language_Codes    Locale::Maketext::Simple
Locale::Codes::LangExt           Locale::Codes::Language_Retired  Locale::Script
Locale::Codes::LangExt_Codes     Locale::Codes::Script            Locale::gettext
Locale::Codes::LangExt_Retired   Locale::Codes::Script_Codes      locale

Probablemente me olvidé de ellos porque no pude hacerlos funcionar. Supongo que nunca lo uso Perly no sé cómo cargar un módulo correctamente. Pero las manpáginas se ven bastante bien. En cualquier caso, algo me dice que encontrarás llamar a un módulo Perl al menos un poco menos difícil que a mí. Y, nuevamente, estos ya estaban en mi computadora - y ni siquiera uso Perl. También hay algunos I18Nque recorrí con nostalgia sabiendo muy bien que tampoco conseguiría que funcionaran.

Respuesta2

Al menos en sistemas GNU, FreeBSD o Solaris, este enfoque de fuerza bruta funciona:

#include <wctype.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  unsigned long i;
  int need_init;
  wctype_t type;
  FILE* to_perl;

  setlocale(LC_ALL,"");
  if (argc != 2) {
    fprintf(stderr, "Usage: %s <type>\n", (argc?argv[0] : "???"));
    exit(1);
  }
  if (!(type = wctype(argv[1]))) {
    fprintf(stderr, "Invalid type: \"%s\"\n", argv[1]);
    exit(1);
  }

  need_init = wctomb(0, 0);

  to_perl = popen("perl -Mcharnames=full -ane '"
                  "printf \"%17s U+%04X %s\n\", join(\" \", @F[1..$#F]),"
                  "$F[0], charnames::viacode($F[0])'", "w");

#ifdef SUPPORT_ROGUE_LOCALES
  for(i=0; i<=0x7fffffff; i++) {
#else
  for(i=0; i<=0x10ffff; i++) {
    if (i == 0xd800) i = 0xe000; /* skip UTF-16 surrogates */
#endif
    if (iswctype(i, type)) {
      int n;
      unsigned char buf[1024];

      if (need_init) wctomb(0, 0);
      n = wctomb(buf, i);

      if (n > 0) {
        int c;
        fprintf(to_perl, "%lu", i);
        for (c = 0; c < n; c++)
          fprintf(to_perl, " %02X", buf[c]);
        putc('\n', to_perl);
      }
    }
  }
  pclose(to_perl);
  return 0;
}

Si bien según C/POSIX, wchar_tes un tipo opaco que no tiene relación con Unicode y solo se garantiza que cubre todos los caracteres admitidos por la configuración regional del sistema, en la práctica, en la mayoría de los sistemas que admiten Unicode, los valores corresponden a los puntos del código Unicode. y las definiciones locales se basan en Unicode.

Unicode está destinado a ser un superconjunto de todos los conjuntos de caracteres conocidos, por lo que al recorrer todos los puntos de código válidos en Unicode (0 a 0xD7FF y 0xE000 a 0x10FFFF) se deben enumerar al menos todos los caracteres admitidos por un conjunto de caracteres determinado.

Aquí, utilizamos la API estándar de configuración regional del sistema para verificar cuáles son de un tipo determinado y convertirlos a su forma codificada en la codificación de la configuración regional. Usamos perly su charnamesmódulo solo para obtener el nombre de un punto de código Unicode determinado.

En las configuraciones regionales que utilizan codificaciones con estado como ISO-2022-JP, nos aseguramos de que el formulario codificado se muestre desde un estado inicial predeterminado.

No he encontrado un sistema que haya instalado configuraciones regionales con una codificación de caracteres con estado, pero al menos en los sistemas GNU, es posible generar algunas para poder crear una configuración regional no autorizada (y al menos las herramientas GNU no funcionan correctamente en esos locales). Por ejemplo, con una configuración regional personalizada que usa ISO-2022-JP con una ja_JPconfiguración regional normal, obtengo:

$ LOCPATH=$PWD LC_ALL=ja_JP.ISO-2022-JP ~/list-type blank
       09 U+0009 CHARACTER TABULATION
       20 U+0020 SPACE
   1B 24 42 21 21 U+3000 IDEOGRAPHIC SPACE

Comparar con:

$ LC_ALL=ja_JP.eucjp ~/list-type blank
       09 U+0009 CHARACTER TABULATION
       20 U+0020 SPACE
    A1 A1 U+3000 IDEOGRAPHIC SPACE

En ISO-2022-JP, la 1B 24 42secuencia ( \e$B) cambia de ASCII a un estado donde los caracteres se expresan como 2 bytes (7 bits) (aquí 21 21 para ese ESPACIO IDEOGRAFICO). Mientras que en EUCJP, son los mismos bytes pero elcambio de estadose realiza invirtiendo el octavo bit ( A1 = 21 | 0x80), lo que lo hace menos apátrida.

Eso significa que en esas codificaciones con estado, hay varias formas de escribir un carácter determinado (por ejemplo, insertando varios de esoscambio de estadosecuencias), y la secuencia mostrada por ese código anterior es solo una de ellas (la canónica de un estado predeterminado inicial).

Mientras que para una configuración regional normal, los caracteres no pueden estar fuera de 0..0xD7FF, 0xE000..0x10FFFF, para unapícaroconfiguración regional, cualquier carácter en el rango admitido por wchar_t puede ser. Por ejemplo, podría crear una configuración regional donde se incluyan los caracteres U+DCBA o U+12345678 (o serían caracteres si estuvieran permitidos).espacios en blanco. Es por eso que querrás compilar ese código para -D SUPPORT_ROGUE_LOCALEScubrirlos, aunque eso significa que lleva mucho más tiempo escanear toda la lista.

No pude usar la solución de @mikeserv porque recodeusa sus propias conversiones, ya no se mantiene y solo admite caracteres Unicode hasta 0xFFFF, y GNU tral menos no funciona con caracteres de varios bytes.

no pude usar@ChrisDownya pythonque no tiene interfaces para las clases de caracteres POSIX.

Probé Perl, pero es falso para puntos de código entre 128 y 255 para configuraciones regionales de varios bytes distintas de UTF-8 y no utiliza las bibliotecas de conversión del sistema.

información relacionada