« first day (2284 days earlier)      last day (817 days later) » 

2:37 AM
@AlfredoMaussa He estado convirtiendo una misma imagen (en formato original de jpg) a png y jpeg a formato binario (0 y 1), El resultado arroja que los dos códigos binarios son diferentes. Por ahora, la respuesta sería no. Sin embargo, este resultado puede tener un margen de error. Te daré un resultado preciso en un rato.
 
3:07 AM
Hice dos análisis, en ambos el resultado es negativo, todos los códigos son diferentes
En el primero, comparamos una imagen WebP y PNG
Ambos en códigos binarios, detecto que ambos tienen el mismo números de caracteres, sin embargo los códigos son diferentes.
En el segundo comparamos una imagen JPG y WebP
Todas las imágenes son convertidas a binario siendo la misma imagen de origen
 
 
4 hours later…
7:13 AM
@RodrigoRamírez No entiendo el problema. Cada formato gráfico (jpg, png, ..) guarda la imagen de distinta manera. ¿Te refieres que sean "iguales" una vez expandida a los pixeles finales?
 
@CandidMoe mismo formato compatibles, diferentes escalas
 
7:41 AM
@farsSharp ¿Qué está comparando? ¿La imagen en disco o la imagen descomprimida?
 
eso tu se lo indicas
 
 
4 hours later…
11:36 AM
@AlfredoMaussa Depende de a qué te refieras con "en binario". Un fichero ya es un montón de bytes, y por tanto está "en binario". Si te refieres a los contenidos del fichero, obviamente han de ser diferentes PNG, JPG, WebM, BMP, etc... pues si fueran iguales serían todos el mismo formato y sólo cambiaría el nombre del fichero
pero el contenido de esos ficheros no te permite recuperar la imagen de forma trivial. Es decir, no se trata de que cada byte del fichero represente un pixel. Por el contrario, cada formato tiene su propia estructura interna y su propio algoritmo para "reconstruir" la imagen
entonces, es necesario código (normalmente una biblioteca) para leer una imagen de un fichero, según su formato, y sacar de ahi la matriz de pixeles. Una vez has hecho ese proceso, la matriz resultante tendrá el mismo tamaño sin que importe el formato del fichero (suponiendo claro que todos guardan la misma imagen) pues ese tamaño sólo depende de la resolución (ancho * alto)
una vez tienes esa matriz, puedes guardarla a su vez en otro fichero "sin formato". En esa matriz cada pixel serán 3 bytes (uno para cada componente RGB), y podrías escribir en un fichero simplemente un byte tras otro ¿te refieres entonces a este resultado cuando dices "en binario"?
en ese caso el resultado tampoco tiene por qué ser el mismo, pues hay formatos "con pérdida" como JPEG y otros "sin pérdida" como PNG
La diferencia entre ambos es que en un formato "con pérdida" la imagen que se recupera al decodificar el fichero no es la misma que la que se metió como entrada, sino una ligeramente diferente. Las diferencias son tan mínimas que el ojo no las detecta, pero gracias a esas pequeñas diferencias se puede lograr un tamaño más pequeño en el fichero resultante (es decir, se comprime más)
JPEG te permite elegir diferentes "calidades" cuanto menor calidad pongas, más conseguirás comprimir el fichero .jpeg, pero más se alejará la imagen de la original cuando la decodifiques. Supongo que habrás visto imágenes jpeg de baja calidad en la que aparecen "artefactos" (zonas cuadradas con pixeles raros, especialmente en las zonas oscuras, que se hacen visibles al aumentar el contraste)
PNG en cambio comprime "sin pérdida". Es decir, la imagen reconstruida al leerla es exactamente igual que la imagen original. Para ello usa algoritmos de compresión que no introducen modificaciones, y por tanto puede comprimir menos
En la parte derecha de este chiste se observan los "artefactos" introducidos por jpeg cuando se elige una compresión muy alta. Alrededor de las letras y trazos aparecen "nubes" de pixeles grises.
 
 
1 hour later…
1:17 PM
@abulafia Me surgió la pregunta porque hice algo que recibe imágenes en formato "binary" vía HTTP file content, y resultó ser agnóstico del formato, tal vez Pillow interpretaba cada formato por separado, pero de pronto la imagen en formato binario era "agnóstica". No lo comprobé.
 
@AlfredoMaussa ¿Agnóstico del formato? ¿Qué quiere decir eso? ¿Que el mimetype no especifica exctacmente qué tipo de imagen es?
De todas formas el tipo de imagen forma parte de la propia secuencia de bytes del fichero, independientemente de la extensión o nombre que éste tenga. Tal vez por eso te funciona aun sin especificar nada. Por ejemplo los primeros 4 bytes dentro del fichero (o del flujo de bytes binario que recibes por http) ya sirve para identificar el tipo de fichero
los ficheros png contienen al inicio las letras "PNG" por ejemplo
Ah, otra cosa, tú eres quien había preguntado por lo de la expresión regular para encontrar palabras que contengan a,i,l, a la que di tres respuestas diferentes ¿no te sirvió ninguna? He caido en la cuenta de que la pregunta en ningún momento contuvo la etiqueta "python", pero yo no sé por qué me obcequé en que era una pregunta sobre python
Seguramente porque me apareció marcada "en naranja" porque estoy suscrito también a la etiqueta regexp, pero la maoyría de preguntas en mi feed son de python
 
@abulafia Sí, que no tuve que especificar el formato.
@abulafia La verdad ya sabía una respuesta, quería hacer la pregunta porque me pareció buena y ver que otras respuesta habían. Estoy esperando por si alguien más responde. Surgió de alguien en inglés que trata de hacer algo para resolver wordle. (la pregunta no es la misma, veo que la cerraron) stackoverflow.com/q/70899516/13636459
 
1:51 PM
Hoy si que costó:
WORDLE (ES) #24 5/6
×
🟨⬜⬜⬜🟨
🟨⬜🟨🟨🟨
🟨🟨🟨🟨⬜
⬜🟩🟩🟩🟩
🟩🟩🟩🟩🟩
 
2:44 PM
@Arcanis-TheOmnipotent y si... no entiendo tu problema...
 
 
2 hours later…
4:23 PM
Wordle (ES) #24 3/6

⬜⬜⬜🟨🟩
⬜⬜🟩⬜🟩
🟩🟩🟩🟩🟩
 
4:55 PM
Wordle (ES) #24 3/6

⬜⬜⬜⬜🟩
🟩🟩⬜🟨🟩
🟩🟩🟩🟩🟩

wordle.danielfrg.com
terrible remonatada
 
Veo que los datos son distintos, el código de prueba es este ``` from fastapi import FastAPI, File

import io
import base64

import numpy as np
from PIL import Image


app = FastAPI()

@app.post("/")
async def create_file(file: bytes = File(...)):

imgencoded=np.frombuffer(file, dtype=np.uint8)
# myimg=Image.open(io.BytesIO(imgencoded)).convert('RGB')

return {'data':b'image/jpeg;base64,'+base64.b64encode(imgencoded),'binary':str(imgencoded)}

```
La cuestión es que `Image.open(array)` lee correctamente la imagen sin especificar el formato, no entiendo cómo lo hace.
*La codificación (~datos)
Y cuando uso un visualizador (app online) de imágenes en base64, tampoco importa en qué formato especifique, el visualizador parece saber el formato sin preguntarlo.
 
@AlfredoMaussa como ya te dije antes la secuencia de bytes de un formato estandar suele comenzar por ciertos bytes (llamados magic numbers) que sirven para saber qué tipo de imagen es. Imprime imgencoded[:4] y veras.
 
5:16 PM
@abulafia Bueno sí, confirmo.
 
 
2 hours later…
7:31 PM
De que sirve un JWT si con una aplicación cualquiera puedo ver el contenido del token?
 
7:54 PM
Normalmente el token se cifra con una clave secreta del servidor
 
Lo que entiendo es que el token es como una llave que te envía el servidor para identificarte en una sesión, así se garantiza que no hay intermediarios recibiendo datos. Solo la persona que inició la petición.
 
o bien lo que contiene no es confidencial
(además de ir cifrado como el resto de cabeceras si la conexión es https)
 
@Christian Además el token es exclusivo para cada usuario, otra persona en otro navegador ve un token distinto.
 
@AlfredoMaussa seguro? yo creía que el token cambiaba según el contenido y la clave :/
@abulafia osea puedo "piratear" el token?
 
@Christian No es diferente a una cookie. Simplemente va en otra cabecera. Es legible para el cliente. Si no quieres que lo sea, debe cifrarla el servidor
creo que puedes pensar en el JWT como un "json" que te envía el servidor, solo que codificado de modo que sea una cadena hexadecimal
lo que contenga es decisión del servidor. Pero al ser público el algoritmo de codificación, cualquiera puede descodificarlo y ver los datos. Insisto, si no quieres que sea así, se cifra en el lado servidor y listo
 
8:01 PM
@Christian De pronto te refieres a un mecanismo de seguridad de encriptación para que los que tienen las bases de datos no puedan ver tu clave. Lo legal es usar un token que encripte esos datos.
* Creo que es ilegal no hacerlo, al menos para las grandes empresas.
 
@AlfredoMaussa Creo que estás confundiendo token con hash
y hash con encriptar
 
buenoo.. confiaré en la información que dice que el JWT es seguro
@app.post("/login")
def login():
    req = request.json
    token = jwt.decode(req["token"], os.environ["SECRET"], algorithms=["HS256"])
    res = db.users.find_one({"username":req["username"], "password":token["password"]})
    print(res)
    return OK
esto estaría bien?
 
@abulafia Pero un token debe estar encriptado no? sino no sería seguro, y lo común es usar sha256 u otros. Sobre todo porque los token se usan para dar privilegios.
 
sha256 es un algoritmo de hashing, no de encriptación
y el token debe estar encriptado si no quieres que el cliente pueda leer lo que contiene o que no pueda manipularlo. No siempre eso es necesario
para oprotegerlo de la vista de otros clientes ya está el protocolo https (que cifra toda la transmisíón)
los tokens no se guardan en bases de datos (al menos no los JWT de los que estamos hablando)
y si se guardaran no se guardarían hasheados con sha256, porque si lo haces ya no puedes volver a leerlos. Un hash es irreversible
 
XD yo lo estoy guardando
 
8:08 PM
@Christian Para qué? El token va y viene en cada comunicación con el cliente. El servidor no necesita guardarlo. Precisamente esa es la gracia de JWT, que hace que el servidor no necesite guardar ningún tipo de estado
así puedes crear muchos servidores "stateless" y permitir el escalado horizontal
 
@abulafia ni idea, no sé por qué se me pasó guardarlo.
Osea debería guardar los datos necesarios del usuario y al iniciar sesión usaría el token?
 
No sé qué estás haciendo exactamente, pero la idea es la siguiente: El usuario inicia sesión con su nombre y contraseña. El servidor verifica que sean las correctas y crea una estructura de datos que identifica quién es el usuario y otra información que puedas necesitar en otros servicios del backend (por ejemplo, el rol del usuario, si es admin o no, etc.). Esa información la codifica en un token jwt y se la envía al cliente
 
En resumen no debes guardar la contraseña en la base de datos sino el token. la contraseña solo se tocaría en frontend del lado del usuario. en el backend verificas es el token.
 
A partir de ahi, el cliente en cada petición posterior a la API enviará en una cabecera ese token. El servidor al recibirlo y decodificarlo sabrá ya quién es el cliente y qué permisos tiene, por lo que no necesita que se autentique de nuevo, ni mirar esa info en la base de datos
@AlfredoMaussa No veo por qué guardar ningún token en la base de datos. Estamos hablando de JWT. Ese token lo reenvía el cliente en cada petición. El servidor no necesita guardarlo. El token contiene toda la información que el servidor necesita
@Christian El uso que haces ahi del token, para transportar la contraseña, no es correcto
el token lo genera el servidor, no el cliente. Es como una cookie
en un endpoint tipo "/login" el cliente enviaría la contraseña como parte de la request normal, no hace falta un jwt para eso
insisto, el jwt es una info que crea el servidor y se la pasa al cliente, como si le dijera "guardame esto y vuelve a dármelo en cada una de las peticiones futuras"
 
pues eso hago
@app.post("/register")
def register():
    req = request.json
    data = {
        "username": req["username"],
        "password": sha256(req["password"].encode()).hexdigest(),
        "account": "simple"
    }
    encode_jwt = jwt.encode(data, os.environ["SECRET"], algorithm="HS256")
    data["token"]=encode_jwt
    db.users.insert_one(data)
    return {"status": "ok", "token":encode_jwt}
 
8:15 PM
Si, pero eso es el registro que crea al usuario
antes en cambio pusiste la función /login en la que un usuario (ya registrado) se identifica
y de aquí veo que la password la pasa en el token:
"password":token["password"]}
además, eso ni siquiera podrás hacerlo funcionar correctamente ya que el token parece venir cifrado con una clave que el cliente no debería tener; os.environ["SECRET"]
 
ya me perdí, no se supone que esa clave debe ser secreta?
 
Es una verificación con dos claves, el usuario ya pone la suya y el servidor poner la segunda. No es necesario que el usuario sepa la clave del "administrador".
 
@Christian Qué clave? La de os.environ["SECRET"]?
 
pues sip
 
efectivamente debe ser secreta. El cliente no la conocerá. Pero si no la conoce ¿cómo cra el token JWT que está enviando cifrado con esa clave?
porque aqui el servidor intenta descifrarlo con esa clave:
token = jwt.decode(req["token"], os.environ["SECRET"], algorithms=["HS256"])
ah, perdon, que ese token fue el que creó el servidor en /register
 
8:20 PM
pues sip @_@
 
creo que ya veo lo que está pasando. Tienes mal algún concepto
/register simplemente sería para dar de alta un usuario. Guarda su nombre y contraseña en la base de datos (la contraseña hasheada). Hasta ahi correcto. Pero no necesita generar ningún JWT
 
por que?
 
Pero está usando la librería de JWT para hashear la clave.
 
/login es quien verifica si un usuario está registrado o no. Recibe username y password y después genera el JWT que ya no necesita contener la password
@AlfredoMaussa No
@Christian Porque si ya generas un JWT en /register ¿para qué existe /login?
/register se supone que se llama una sola vez. Cuando el usuario ya está en la base de datos no se puede registrar de nuevo
en cambio /login se puede llamar todas las veces que haga falta. Sirve para ver si el usuario está en la base de datos y si se sabe la contraseña
el JWT es una especie de "recibo" que dice "ok, estás registrado y correctamente autenticado"
el cliente deberá presentar ese JWT en las restantes funciones del backend (al menos las que necesiten autorización)
@AlfredoMaussa JWT no hashea y menos claves
para hashear claves se usan otras librerías como sha256 (que de hecho es la que está usando para hashear la clave, como se ve aqui)
"password": sha256(req["password"].encode()).hexdigest(),
 
@abulafia haa... shap, ahora ya entendí, gracias :D
 
8:28 PM
El JWT contiene información, como por ejemplo esta: { "username": "Christian", "is_admin": true }
esa info la genera el servidor ante una ejecución de /login
y se la manda al cliente en un formato que el cliente no pueda alterar
(para eso se usa HMAC y la clave secreta del servidor)
el cliente a su vez la manda al servidor al acceder a cualquier otro endpoint como por ejemplo /show/me. El servidor mira si viene un token JWT (si no viene deniega el acceso), y de él extrae el json, que diría { "username": "Christian", "is_admin": true }. En base a esa info produce la respuesta apropiada para ese usuario
el JWT ha permitido así acceder a un endpoint "protegido" sin necesidad de volver a enviar ninguna contraseña
el JWT "demuestra" que la contraseña correcta ya había sido enviada previamente (a la función /login)
El token JWT típicamente es enviado por el cliente en la cabecera Authorization: Bearer y no como parte del payload
 
 
1 hour later…
9:41 PM
@Christian JWT es seguro si lo sabes usar.
 
9:56 PM
@MauricioContreras creo que eso aplica con todo
esperemos que lo este usando bien
 
 
2 hours later…
11:42 PM
Me acabo de enterar que hay un grupo musical llamado "la oreja de Van Gogh", el nombre es curioso
 

« first day (2284 days earlier)      last day (817 days later) »