TARDÍGRADOS

Ciencia en español -ʟᴀ ʀᴀᴢóɴ ᴇsᴛá ᴀʜí ғᴜᴇʀᴀ-

El número π (PI) visto desde una n-bola

Posted by Albert Zotkin on August 24, 2021

Posted in Matemáticas | Tagged: , , , , , , , , | Leave a Comment »

Método de autosimilaridad para detectar teorías falsas de la relatividad

Posted by Albert Zotkin on August 19, 2021

Posted in criptografía | 1 Comment »

Cómo “robar” bitcoins con una modesta tarjeta gráfica NVIDIA

Posted by Albert Zotkin on July 15, 2021

Hola amigos de Tardígrados. El propósito principal del siguiente documento informático, no es enseñar a robar Bitcoins, eso estaría muy feo sino demostrar la robustez de la protección criptográfica de Bitcoin, y mostrar de paso, con un caso práctico, la casi inexpugnable muralla que ofrece esa criptografía contra posibles ataques, que los hay. ¿Es tan segura esa protección criptográfica?. Sí. Estamos hablando de cadenas de 256 bits. Esas contraseñas serán las semillas para generarán las llaves privadas y las direcciones públicas de Bitcoin. O sea, estamos hablando de un número monstruosamente grande de combinaciones. Ese número entero es:

\displaystyle N =2^{2^{2^{3}}}=1157920892373161954235709850086879078532699846656405640394575840079131\ 29639936

que, como vemos, tiene 78 cifras decimales. Para intentar hacernos una idea de lo que ese número representa, supongamos que tenemos una lista de 135 direcciones de Bitcoins, que queremos atacar. Atacar, aquí quiere decir descubrir la clave privada desde la dirección publica. Entonces la probabilidad de dar con una de esas 135 claves sería de:

\displaystyle P =\frac{135}{ 2^{2^{2^{3}}} } = 1.1658827549377500244271575014780539421006600491989 \text{ x } 10^{-75}

Es decir, aun suponiendo que nuestra computadora fuera capaz de procesar 1 millón de direcciones por segundo, tendríamos por delante aún unos

\displaystyle t =\frac{ 2^{2^{2^{3}}} }{135 \times 1000000} = 8.5771917953567552165608137043472524335755544196771 \text{ x } 10^{68} \text{ segundos}

para encontrar la primera de esas 135 direcciones de la lista que queremos atacar. Creo que ni Matusalén conseguiría vivir tanto para ver como se consigue ese primer hallazgo 🙂

Mi tarjeta gráfica es una NVIDIA GeForce GT 430. Escribiremos un pequeño programa para Node.JS , en el que aceleraremos la computación mediante tarjeta gráfica, es decir, usaremos la GPU de la tarjeta gráfica, en lugar de la CPU de la computadora. Para la computación con tarjeta gráfica usaremos el módulo gpu.js, el cual posee un javascript de aceleración muy interesante. Para trabajar con bitcoins, yo uso el módulo bitcore-lib, donde además de las herramientas para bitcoin también trae otras interesantes utilidades. Empecemos abriendo un editor de texto cualquiera, y escribamos las primeras instrucciones de nuestro programilla, que como sabemos deberá ser escrito en lenguaje javascript, ya que es para Node.JS .

  1. const {GPU} = require(‘./gpu.js’);
  2. const bitcore = require(‘bitcore-lib’);
  3. const crypto = require(‘crypto’);
  4. const fs = require(‘fs’);
  5. const gpu = new GPU();
  6. var argv = require(‘yargs’)
  7. .usage(‘Usage: $0 –range [num] –samples [num]’)
  8. /*.demand([‘range’,’samples’])*/
  9. .argv;
  10. const jsonutil = require(‘jsonutil’);
  11. const JSONStream = require(‘JSONStream’);
Los módulos gpu.js, yargs, jsonutil y bitcore-lib, los puedes decargar desde npm. Los módulos crypto y fs, no, porque ya vienen incluidos en el propio Node.js.
Nuestro programilla, que trabajará desde una consola DOS de windows mediante comandos, tiene el módulo yargs, con el que definimos dos argumentos para pasar en la linea de comandos al ser ejecutado. Nuestro primer argumento será –range [num], y en él especificaremos el número de coincidencias que deseamos (obviamente, desearíamos un número de coincidencias pleno, pero como esta es sólo una herramienta demostrativa, tenemos que dar juego a las coincidencias. Las direcciones públicas de bitcoin poseen 34 caracteres, porque están codificadas en Base58, por lo tanto el juego podrá ir desde 1 coincidencias hasta el pleno de 34. ¿Por qué 34?. Porque son números hexadecimales de 50 dígitos, que están codificados en Base58. Después usaremos en nuestra linea de comando el argumento –samples [num], que será el número de direcciones que queremos en nuestra lista de resultados, Obviamente si nuestra lista de direcciones objetivo es de 135, el número num que sigue a –samples no podrá ser nunca mayor a esos 135.
Sigamos escribiendo nuestro código en nuestro editor de textos favorito:

  1. const range = argv.range?parseInt(argv.range):4;
  2. var max_limit = argv.samples?parseInt(argv.samples):10;
  3. const file = “keys-“+range+“.json”;
  4. var results_file = “keys-“+range+“.json”;
  5. var jsonwriter = JSONStream.stringify();
  6. var jsonwriter_file = fs.createWriteStream(results_file);
  7. jsonwriter.pipe(jsonwriter_file);
  8. const objetive_addrs =[// list of bitcoin public addreses, can’t be empty
  9. //…TODO
  10. ];
  11. const objetive_size = 100;
  12. const m = Fill(objetive_size);
  13. const render = gpu.createKernel(function(a,m) {
  14. var h = a[this.thread.y][this.thread.x];
  15. var c = m[this.thread.y][this.thread.x];
  16. if(h == c) return h;
  17. return 1;
  18. }).setOutput([42, objetive_size]);
  19. var n=0;
  20. var time0 = Date.now();
  21. var total=0;
  22. var stop = 8;
  23. var keys = {
  24. phrase:null,
  25. private_key:null,
  26. wif:null,
  27. public_address:null,
  28. objetive_addrs:null
  29. };
En las lineas 14 y 15 pasamos los argumentos –range y –samples a sus respectivas variables range y max_limit. En las lineas 16 y 17 nombramos 2 archivos con el mismo nombre.. En las lineas 18 a 20 creamos los streams para escribir el archivo results_file.

El resto del programilla es como sigue:

  1. /***********************************************************************************************************/
  2. console.log(\x1b[32m***************************************************\x1b[0m”);
  3. console.log(\x1b[32m*******************\x1b[0m\x1b[92m THE IMPOSSIBLE\x1b[0m\x1b[32m ****************\x1b[0m”);
  4. console.log(\x1b[32m*******\x1b[0m\x1b[92mIt’s kind of fun to do the impossible\x1b[0m\x1b[32m*******\x1b[0m”);
  5. console.log(\x1b[32m—————RANGE \x1b[1m%s\x1b[0m \x1b[35mwith samples\x1b[0m \x1b[1m%s\x1b[0m \x1b[35mSTARTED—————\x1b[0m”,range,max_limit);
  6. console.log({miners_size:objetive_adrs.length});
  7. while(n < max_limit){
  8. var ar = FillArray(miners_size);
  9. var a = ar[0];
  10. var b = ar[1];
  11. var p = ar[2];
  12. var w = ar[3];
  13. var r = render(a,m);
  14. var t = filterArray(r, a, b, p, w, m, range);
  15. if(t.length){
  16. for(var i=0;i<t.length;i++){
  17. keys.phrase = t[i][0];
  18. keys.private_key = t[i][1];
  19. keys.wif = t[i][2];
  20. keys.public_address = t[i][3];
  21. keys.miner__address = t[i][4];
  22. jsonwriter.write(keys);
  23. var pair = highlight(t[i]);
  24. keys.phrase = pair[0];
  25. keys.private_key = pair[1];
  26. keys.wif = pair[2];
  27. keys.public_address = pair[3];
  28. keys.miner__address = pair[4];
  29. consola(keys);
  30. var time = Date.now()time0;
  31. total += time;
  32. time0 = Date.now();
  33. console.log(\x1b[33mNew keys has been appended to file \x1b[1m%s\x1b[0m. \x1b[33mDuration of this sample: \x1b[31m\x1b[1m%s\x1b[0m \x1b[33mseconds\x1b[0m”,results_file, time/1000);
  34. }
  35. n++;
  36. if(n==max_limit) {
  37. jsonwriter.end();
  38. console.log(“max-limit of %s samples reached. Job terminated.”,max_limit);
  39. console.log(\x1b[33m – Total \x1b[1mduration\x1b[0m \x1b[33mof job: \x1b[31m\x1b[1m%s\x1b[0m \x1b[33mseconds – \x1b[0m”,total/1000);
  40. break;
  41. }
  42. }
  43. }
  44. /******************************************************/
  45. function FillArray(size){
  46. var a = [];
  47. var b = [];
  48. var p = [];
  49. var w = [];
  50. for(var j = 0;j < size;j++){
  51. var t = [];
  52. var hash = crypto.randomBytes(32);
  53. //var hash = bitcore.crypto.Hash.sha256(crypto.randomBytes(32));
  54. var bn = bitcore.crypto.BN.fromBuffer(hash);
  55. var privateKey = new bitcore.PrivateKey(bn);
  56. var address = privateKey.toAddress().toString(‘hex’);
  57. b.push(hash.toString(‘hex’));
  58. p.push(privateKey.toString(‘hex’));
  59. w.push(privateKey.toWIF().toString(‘hex’));
  60. for(var i = 0;i < address.length;i++){
  61. t.push(address.charCodeAt(i));
  62. }
  63. a.push(t);
  64. }
  65. return [a,b,p,w];
  66. }
  67. function FillMiners(size){
  68. var a = [];
  69. var k = 0;
  70. for(var j = 0;j < size;j++){
  71. if(k == objetive_adrs.length)k=0;
  72. var address = objetive_adrs[k];
  73. k++;
  74. var t = [];
  75. for(var i = 0;i < 42;i++){
  76. if(i<address.length)
  77. t.push(address.charCodeAt(i));
  78. else
  79. t.push(0);
  80. }
  81. a.push(t);
  82. }
  83. return a;
  84. }
  85. function FillMiners2(size){
  86. var a = [];
  87. var k = 0;
  88. for(var j = 0;j < size;j++){
  89. if(k == objetive_addrs.length)k=0;
  90. var address = objetive_addrs[k];
  91. k++;
  92. var t = [];
  93. for(var i = 0;i < 42;i++){
  94. if(i<address.length)
  95. t.push(address.charCodeAt(i));
  96. else
  97. t.push(0);
  98. }
  99. a.push(t);
  100. }
  101. return a;
  102. }
  103. function check(a) {
  104. return a != 1;
  105. }
  106. function filterArray(r, a, b, p, w, m, range){
  107. var f = [];
  108. for(i in r){
  109. var s = r[i].filter(check);
  110. if(s.length >= range){
  111. var a1 = new Buffer.from(a[i]).toString();
  112. var b1 = b[i];
  113. var p1 = p[i];
  114. var w1 = w[i];
  115. var m1 = new Buffer.from(objetive_adrs[i]).toString();
  116. f.push([b1,p1,w1,a1,m1]);
  117. }
  118. }
  119. return f;
  120. }
  121. // funciones para imprimir resultados en la consols DOS de Winsdows
  122. function highlight(keys){
  123. var pa = keys[3].split();
  124. var ma = keys[4].split();
  125. const h =\x1b[1m’;
  126. const t =\x1b[0m\x1b[32m’;
  127. const y =\x1b[33m’;
  128. const g =\x1b[32m’;
  129. for(id in pa){
  130. if(pa[id] == ma[id]){
  131. pa[id] = ma[id] = h+ma[id]+t;
  132. }
  133. }
  134. var b = y+keys[0]+\x1b[0m’;
  135. var p = y+keys[1]+\x1b[0m’;
  136. var w = y+keys[2]+\x1b[0m’;
  137. var pa2 = g+pa.join()+\x1b[0m’;
  138. var ma2 = g+ma.join()+\x1b[0m’;
  139. return [b,p,w,pa2,ma2];
  140. }
  141. function consola(json){
  142. var a = JSON.stringify(json,null,8);
  143. a = a.replace(/”/g,);
  144. a = a.replace(/\\u001b/g,\x1b’);
  145. process.stdout.write(a);
  146. }
  147. /******************************************************/

Saludos

Posted in Bitcoin, criptografía, Criptomonedas, informática | Tagged: , , , , , , , , , , , | Leave a Comment »

Formalismos incorrectos de la Relatividad Especial

Posted by Albert Zotkin on July 6, 2021

“Quien parte de principios erróneos termina en conclusiones equivocadas”
Uno de los embrollos más tremendos en Física Teórica surge cuando intentamos calcular la velocidad de una fuente de luz mediante la medida de su desplazamiento Doppler, o cuando calculamos cualquier magnitud física que implica velocidades relativas entre fuente de luz y observador. A menudo es materia de discusión el tema de si la velocidad de la luz es independiente de la velocidad de la fuente, o si no lo es respecto a la velocidad del observador. Una cosa parece estar clara, la respuesta a esta clase de cuestiones es que las velocidades relativas parecen depender de la teoría desde la que se consideran. La teoría de la Relatividad Especial, y la Teoría General de la Relatividad, han contribuido notablemente a ese embrollo brutal.

Sería interesante poder separar el grano de la paja seleccionando formalismos matemáticos que no incluyen velocidades explícitamente. Por lo tanto, en lugar de trabajar con velocidades relativas podemos trabajar con energía total, energía cinética y momento. Al realizar esta siega evitamos manejar resultados que pudieran ser vistos como dependientes de la teoría.

Así pues, un “formalismo correcto” será desde ahora aquel que no exhibe explicitamente velocidades, “formalismo incorrecto” será aquel que contenga explícitamente velocidades.

Empecemos con algunos ejemplos, que serían independientes de la teoría desde la que se consideran, y que serían “correctos“:

A. Fórmulas correctas:

A1. Energía en reposo de un cuerpo

\displaystyle E_0 = m_0 c^2

A2. Relación Energía-momento

E^2 = (m_0 c^2)^2 + (p c)^2

A3. Doppler relativista expresado en función de E/E_0

f = f_0 \left ( \frac{E}{E_0} \pm \sqrt{ (\frac{E}{E_0})^2 - 1 } \right )

A4. Energía total expresada como energía en reposo más energía cinética

A5. Momento relativista expresado en función de E, E_0 and c

p = \pm E_0 \cfrac{\sqrt{(E/E_0)^2 - 1}}{c}

B. Algunas fórmulas “incorrectas” que dan respuestas “correctas” según se especifica en la sección A.

B1. Doppler relativista expresado en función de v,

f = f_0 \sqrt{\cfrac{1+v/c}{1-v/c}}

B2. Momento relativista

p = m_0 \cfrac{v}{ \sqrt{ 1-\frac{v^2}{c^2} } }

B3. Energía cinética relativista

K = m_0 c^2 \left (\cfrac{1}{ \sqrt{ 1-\frac{v^2}{c^2} } } - 1 \right)

B4. Energía total expresada en función de la energía en reposo y la velocidad v

E = m_0 \cfrac{c^2}{ \sqrt{ 1-\frac{v^2}{c^2} } }

Estas fórmulas de la sección B son “incorrectas“, según la definición de “correcto” ofrecida arriba. Podemos ver que cualquier fórmula de la sección A puede ser hallada desde estas de la sección B. Pero eso sólo significa que las fórmulas en B pertenecen a una teoría ( por ejemplo la relatividad especial) donde la velocidad es dependiente de la teoría.

Los siguientes ejemplos pertenecen a una teoría distinta desde la que se pueden derivar las mismas fórmulas “correctas” expresadas en la sección A.

C. Algunas fórmulas alternativas que dan la respuesta correcta

C1. Doppler Relativista Galileano expresado en función de v,

f = f_0 \exp \left ( \frac{v}{c} \right )

C2. Momento relativista Galileano,

p = m_0 c \sinh \left (\frac{v}{c}\right)

C3. Energía cinética Galileana

K = m_0 c^2 \left (\cosh (\frac{v}{c}) - 1 \right)

C4. Energía total Galileana expresada en función de la energía en reposo y velocidad v

E = m_0 c^2 \cosh \left (\frac{v}{c} \right)

Según la definición de “correcto“, las fórmulas en la secciones B y C son “incorrectas” porque incluyen explícitamente la velocidad v ( así pues v es dependiente de la teoría), pero desde cada conjunto de fórmulas se pueden derivar las fórmulas correctas de A.

También sería interesante incluir algunos ejemplos desde la mecánica Newtoniana, y ver por qué la mayoría de ellos no pueden ser incluidos en la sección A de fórmulas “correctas“,

D. Fórmulas de la mecánica Newtoniana que son “incorrectas“, aunque no incluyen explicitamente la velocidad v:

D1. Doppler relativista Newtoniano expresado en función de E/E_0

f = f_0 \left (1 \pm \sqrt{\frac{2E}{E_0} - 2} \right )

D2. Momento Newtoniano expresado en función de E   , E_0    y c

p = \pm E_0 \cfrac{\sqrt{\frac{2E}{E_0} - 2}}{c}

La conclusión es clara. Podemos expresar la ratio “correctav/c en función de la energía total E y la energía en reposo E_0    , como

\cfrac{v}{c} = \pm \sqrt{1 - \frac{E_0^2}{E^2}}

o como

\cfrac{v}{c} = \pm \cosh^{-1}( \frac{E}{E_0})

Por lo tanto, cualquier teoría que produzca una ratio diferente sería “incorrecta” en el sentido de que no daría respuestas “correctas“, tal y como están definidas en la sección A.

La mecanica Newtoniana da la ratio

\cfrac{v}{c} = \pm \sqrt{\frac{2E}{E_0} - 2}

La Relatividad Especial y la Relatividad Galileana Completa (el conjunto de fórmulas que he ofrecido en la sección C) dan la ratio “correcta“, por lo tanto son indistinguibles experimentalmente la una de la otra, sólo se distinguen desde sus postulados y formalismos, pero nunca desde sus predicciones observables.

Saludos formales e incorrectos a todos

Posted in Relatividad | Tagged: , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

Materia Oscura: Mi hipótesis, que ahonda en la ruptura espontánea de simetría como modelo

Posted by Albert Zotkin on May 16, 2021

¿Qué es la materia oscura?. ¿Por qué los modelos actuales no son capaces de describir correctamente lo observado?. La materia oscura es una anomalía astrofísica. Una anomalía es una discrepancia entre la teoría y la observación, lo cual en negativo, puede indicar tres cosas, que la teoría no es correcta, que no sea correcta la observación, o que no sean correctas ambas. Aquí supondremos que la observación es correcta, y lo que se observa es que la mayoría de las galaxias y cúmulos de galaxias giran alrededor de sus respectivos centros más rápido de lo esperado. O más exactamente, sus rotaciones se comportan como si fueran las de discos compactos rígidos, más que si fueran fluidos.

En este breve artículo explicaré qué es, en mi opinión, la materia oscura, cómo se forma, y qué efectos observables presenta.

Imaginemos una playa bastante grande y plana, llena de fina arena. Unos niños juegan en ella, y hacen un bonito castillo de arena.

El proceso por el que esos niños han construido el castillo de arena es simple: Primero amontonan arena, formando un buen montón de arena húmeda, que no se desmorone fácilmente. Evidentemente, la arena no la han traído de otro lugar, sino que es la arena que se encuentra en ese mismo sitio, pero amontonada en cierta cantidad. ¿Qué ocurre?. Pues ocurre que al amontonar arena, los niños han creado un pequeño foso alrededor del montón. La arena que hay de más en el montón es precisamente la que falta alrededor. Eso, que parece tan obvio, no son capaces de verlo los científicos y astrofísicos actuales. Estos sabios astrónomos se lían tanto con sus difíciles y engorrosas teorías que no son capaces de ver lo obvio, el bosque. Los árboles de su corta visión les impide ver el bosque. Y el bosque es simple. Cuando la gravedad amontona materia para la formación de una galaxia, no trae materia de muy lejos, sino que es precisamente la materia local la utilizada. Una galaxia no es más que un montón de arena en una playa casi infinita y muy plana. ¿Qué ocurre a ese montón de materia que llamamos una galaxia?. Pues ocurre que alrededor de ella queda un foso, un “anti-montón” de materia. ¿Qué significa eso?. Significa que si la media de densidad de materia entre estrellas de una galaxia es de 0.1 átomos de hidrógeno por centímetro cúbico, en uno de esos fosos gravitacionales el promedio será significativamente menor. Eso, traducido al terreno del potencial gravitatorio implica que existe realmente una modificación de la Ley de Gravitación Universal de Newton. Un típico potencial clásico (de Newton), es simplemente una ley del inverso de la distancia:

\displaystyle \phi_c(r) =- \frac{GM}{r}

Pero, esa ley de gravitación no explica, en su sencillo potencial, el comportamiento anómalo de la rotación de las estrellas en las galaxias, ni de las galaxias en cúmulos. ¿Qué ocurre?. ¿Es la Ley de Gravitación Universal incorrecta?. El señor Einstein se apresuró hace más de cien años a decir que sí, que la Ley de Newton es incorrecta, que le perdonásemos a él, el señor Einstein, por enmendar a un gigante como Newton, al proponer su Relatividad General. Pero, resulta que la Relatividad General de Einstein tampoco es capaz de explicar, ni predecir esa anomalía que llamamos materia oscura. Aquí vamos a ver, por qué todo esto falla. Dejando a parte la Relatividad General, y usando sólo la aparentemente sencilla ley de gravitación de Newton, veremos cómo debe ser el potencial de un sistema galáctico, donde entran en juegos miles de millones de masas solares. El potencial Newtoniano indicado arriba, nos da una grafica en función de la masa M de la galaxia, y su distancia r al baricentro, como la siguiente:

La linea amarilla representa el nivel cero de potencial, el cual nunca se alcanza, ni siquiera en una distancia r infinita. Es decir, que todos los valores reales de potencial son negativos, para un potencial Newtoniano. Pero, ahora vamos a considerar el potencial modificado, de tal forma que esa función φ ya no será exactamente una ley del inverso de la distancia. Y su representación gráfica será algo más compleja:

Aquí vemos que parte de la curva ha traspasado la linea amarilla de potencial cero, para formar un “anti-montón”, un foso gravitacional, que tendrá un valle (concavidad) finito, pero que recupera su tendencia a aproximarse al potencial cero con la distancia. Eso significa que si la linea amarilla representa espacio donde la densidad de materia bariónica es en promedio 0.1 átomos de hidrógeno por centímetro cúbico, entonces la parte de la curva que está por encima de esa línea amarilla representa espacio donde la densidad de materia es menor a ese promedio. Esa es la materia oscura: vacío cósmico donde la densidad de materia bariónica es significativamente menor al valor promedio para el se que se define un potencial gravitatorio igual a cero.

Si ampliamos la escala de la gráfica del nuevo potencial, vemos que la curva vuelve a ser asintótica, pero ahora desde valores de potencial positivos, hacia la linea amarilla de potencial cero:

Podemos explicitar esa curva de potencial gravitatorio, como un potencial newtoniano modificado, y su función sería exactamente una Onda de Ricker:

\displaystyle \phi(r)=-\frac{2}{\sqrt{3 \sigma }\pi ^{1/4}}\left(1-\left(\frac{r}{\sigma }\right)^2\right)e^{-\frac{r^2}{2 \sigma ^2}}

Donde σ es la desviación media. Esto indica también, que este potencial gravitatorio está relacionado con la viscosidad newtoniana, ya que la onda de Ricker es una solución a las ecuaciones diferenciales de navier-stokes y que fue propuesta por Ricker en el año 1943.

Pero, ¿por qué este nuevo potencial gravitatorio puede explicar la anomalía de la materia oscura?. Lo explica por la sencilla razón de que no existen masas negativas. Las masas son siempre de un único signo, y siempre se atraen. Por lo tanto, al existir potencial por encima de la linea de potencial cero, esas zonas se comportan como si fueran masa extra, aunque sólo es vacío con densidad de materia muy por debajo del promedio que marca la linea amarilla. Lo cual significa que el vacío también atrae, como si fuera una masa. De hecho las masas tienden a atraerse porque existe un vació entre ellas que es mayor que el vacío exterior a ellas. Un gas se expande siempre hacia las zonas de menor densidad, nunca al contrario.

Pongamos ahora una masa de pruebas en la cúspide entre el foso y el potencial del sistema gravitatorio en cuestión. Esa masa quedará en equilibrio inestable, pudiendo caer hacia el baricentro del sistema o hacia el foso. En eso consiste la ruptura espontánea de simetría.

¿por qué algunas galaxias y cúmulos no presentan cantidades significativas de materia oscura, y otras sí, si parecen ser de tamaños muy parecidos?. Cuando una galaxia, o un cúmulo de galaxias, se forma muy lentamente, en comparación con el tiempo medio de formación, lo que llamamos materia oscura, y que aquí yo llamo foso gravitatorio, no llega a tener mucha significación. Si hablamos de foso diremos en ese caso que la profundidad del foso gravitatorio de una galaxia que se ha formado muy lentamente es poco profundo o inexistente. Esto indica, que a la inversa, esta hipótesis predice que la materia oscura se evapora. Un foso muy pronunciado, porque la galaxia se formó muy rápidamente, acabará deshaciéndose, porque la materia poco a poco se irá dispersando, cayendo hacia el foso, ya sea desde fuera del sistema o desde dentro.

¿Cuanto tiempo sería necesario para que una galaxia o un cúmulo de galaxias evaporara toda su materia oscura, o lo que es lo mismo, para que el foso gravitatorio se deshiciera?. Dependería de muchos factores, pero grosso modo, podemos decir que necesitaría el mismo tiempo que empleó para su formación.

Pongamos algún ejemplo. La galaxia NGC 1052-DF2 posee muy poca materia oscura o ninguna. Eso, según mi hipótesis, indica que es una galaxia muy antigua, con una edad aproximada del doble de la edad de las galaxias promedio de su tamaño y forma que sí muestran materia oscura.

Esa galaxia sería tan antigua, ya sea porque se formó muy lentamente, y por lo tanto no formó foso, o ya sea porque se formó en un tiempo estándar, como cualquier otra galaxia media, pero su foso se deshizo poco a poco al cabo de un tiempo aproximadamente igual al de su formación. En cualquiera de los dos casos, esa galaxia tiene doble edad que las galaxia que sí exhiben materia oscura.

Y hasta aquí llegó el post de hoy.
Saludos

Posted in Astrofísica, Cosmología, Matemáticas | Tagged: , , , , , , , , , , , , , , , , , , , , , , , , , , | 1 Comment »

JHS: Java Hypertext Script

Posted by Albert Zotkin on April 23, 2021

Hola amigo de Tardígrados . Me parecía injusto, que siendo NODE.js una plataforma de programación tan potente, con la utilización del lenguaje Javascript, no pudiera competir en igualdad de condiciones con el lenguaje PHP, en cuanto a la creación dinámica de paginas web se refiere.
Es habitual ver plantillas de páginas web donde aparecen secciones bien acotadas de código PHP. Eso quiere decir que esas páginas están destinadas a alojarse en un servidor, y cuando un cliente visita el servidor, el código PHP de la página se ejecuta antes de ser enviada. Pongamos un ejemplo sencillo. Sea la siguiente plantilla de página web:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 
$name ="Albert";
?>
<html><head>
<style>
	body{
		background-color:#feffee;
		color:red;
		font-weight:bold;
		font-size:18pt;
 
	}
	#nombre{
		color:green;
		font-weight:bold;
		font-size:20pt;
	}
</style>	
</head>
<body >
<div><p>Mi nombre es: <span id="nombre"><?php echo $name; ?></span></p></div>
</body>
</html>
Esa sencilla página web se vería en el navegador del visitante (cliente) así:

Es decir, vemos que en el código fuente de la página antes de ser enviada por el servidor, existen dos áreas bien acotadas para código PHP. Esas áreas se definen con la clausula (tag) de apertura <?php y la de cierre ?>. Todo lo que está fuera de esas cláusulas es código html, u otras clases de códigos, como javascript del lado del cliente. Para que esa página, que es una mezcla de html y php, funcione, el archivo que se aloja en el servidor tiene que tener la extension php. En nuestro caso, el archivo se llama test-2.php. Si echamos un vistazo al código fuente de la pagina web que nos presenta el servidor, vemos que no aparece ningún código PHP. Sólo vemos código PHp ejecutado, es decir, todo lo que PHP escribió mediante la función echo o alguna otra función más de inprimir. Si el administrador de ese servidor, por la causa que sea, le pone la extensión html a ese archivo mixto, el visitante podrá ver el código php que hay escrito, y la página se presentará incorrectamente. Cambiemos la extensión a nuestro archivo test-2.php por test-2.html, y veamos qué es lo que aparece en nuestro navegador cuando visitamos ese servidor:

De momento, lo que vemos es que ya no aparece el nombre Albert, porque estaba definido dentro de la variable $name del código php. Si ahora echamos un vistado al código fuente de la página podremos ver todo ese código php, y eso es un grave error del webmaster de ese servidor. Porque, efectivamente, además de que ese código php no se ejecuta al ser requerida la página por el cliente, es enviado junto con todo el código restante, que si es código del lado del cliente. PHP es sencillamente código siempre del lado del servidor, el cliente nunca debería ver los scripts php al requerir páginas web dinámicas escritas en ese lenguaje. Con JavaScript existe aún más confusión, ya que existe JavaScript del lado del servidor, y JavaScript del lado del cliente-navegador (browser). Esencialmente, el paradigma de JavaScript del lado del servidor se llama NODE.js. Pero, con NODE.js podemos hacer no Ese entorno de programación multiplataforma posee pocas caracteristicas visuales, pues sólo es capaz de imprimir texto en la consola, y no está pensado para servir páginas web dinámicas como sí hace, y muy bien, PHP. Aunque sí puede hacerlo tambien muy bien, si el programador dedica algún tiempo a perfeccionar esas carateristicas.
Vamos a ver cómo podemos servir páginas dinámicas mediante NODE.js de la misma forma que lo hace PHP. Para ello lo primero que vamos a hacer es nuestro servidor de páginas web en NODE.js. Nuestrp servidor web lo pondremos a la escucha por el puerto 5774 de nuestra computadora, y a todo aquel que lo visite, le saludaremos desde nuestra página de inicio, que llamaremos index.jhs.
Evidentemente, para todo este proyecto, debemos tener instalado ya NODE.js en nuestra computadora, y funcionando correctamente.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const Net = require('net');
const server = new Net.Server();
var port = 5774;
server.listen(port, function() {
	console.log('\x1b[32mNuestro\x1b[0m \x1b[92mSERVIDOR'+ 
	'LOCAL\x1b[0m \x1b[32ma la escucha por '+  
	'el PUERTO\x1b[0m \x1b[93m5774\x1b[0m');    	 
	});
	
server.on('connection', function(socket) {
	socket.on('data', function(chunk) {
		socket.write([
		'HTTP/1.1 200 OK',
		'Content-Type: text/html',
		'Accept-Ranges: bytes',
		'Connection: keep-alive',
		].join('\n') + '\n\n'
		);			
		var html = 
		"<!doctype html>\r\n"+
		'<html lang="es"><head>'+
		'<meta charset="utf-8">'+
		'<meta name="viewport" content='+
		'"width=device-width, initial-scale=1">'+
		'<meta http-equiv="content-type" content='+
		'text/html; charset=utf-8"></head>'+
		'<body><div align="center"><h1>FORMATEANDO '+
		'CARACTERES ESPECIALES DE UTF-8</h1>'+
		'<h2>áéíóúñü-°!"#$%&/()=?¡@-ÁÉÍÓÚÑÜ</h2>Esto '+
		'es una prueba con la ñ y los acentos ò, y,'+
		'<br>como sabrás, estás visitando nuestro<br>'+
		'<b>SERVIDOR LOCAL</b> por el <b>PUERTO '+
		'5774</b></div></body></html>';
    			  				   
		socket.write(html);
		socket.end();		
    });  
});
Guardamos este script en nuestro directorio de trabajo con el nombre server.js, y lo ejecutamos en nuestra consola (Windows MS-DOS, Linux, la que tengas), mediante la linea de comandos: node server.js, o simplemente con node server. Entonces, si todo ha ido bien, aparecerá en nuestra consola el log siguiente:
Ahora ya podemos abrir un navegador y visitar la página de nuestro servidor, cuya dirección será http://localhost:5774/. Este servidor sólo será accesible dentro de tu red local LAN, porque, presumiblemente, no habrás hecho un forward de ese puerto 5774 en tu router para tu conexión de internet. Y la pagina web que veremos en nuestro navegador será algo así:
Ahora ya estamos en disposición de mejorar nuestra pagina web, y hacer nuestro Java Hypertext Script . Pasemos a la siguiente página

Posted in informática | Tagged: , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

¿Qué es el tiempo?¿Qué rumbo toma la consciencia en el multiverso?

Posted by Albert Zotkin on April 18, 2021

Hola amigo de Tardígrados . Gracias por quedarte un rato leyendo mis reflexiones. Hoy voy a volver a repensar sobre qué es el tiempo. Para poder hacerlo de una forma nueva e inesperada usaré un concepto peculiar de multiverso .
Para los que aún no saben qué es el multiverso, diré que es simplemente el conjunto de posibles universos, el nuestro incluido, con cada universo teniendo su propias leyes naturales. Pero, aquí consideraré un Multiverso de Nivel III. En esta clase de multiverso, los universos son estáticos, es decir, no evolucionan en el tiempo, sino que permanecen eternamente invariables e iguales a sí mismos. Desde este punto de partida cabe preguntarse entonces, ¿qué es el tiempo?. Si los universos son estáticos, el tiempo en ellos no existe, ¿cómo emerge el tiempo tal como lo experimentamos nosotros en nuestro universo?. La respuesta no se hace esperar: Nuestro universo, y la experiencia del tiempo y el espacio que sentimos, es sólo una ilusión que emerge de nuestra consciencia. Entonces, nuestro universo, tal como lo experimentamos, sería tan sólo la ejecución de secuencias de un multiverso en nuestra consciencia. mente o psique.
La hipótesis es como sigue: nuestra experiencia vital en nuestro mundo, nuestro universo, es simplemente la experimentación de un tránsito constante de un universo estático hacia otro. Cada universo estático sería algo así como el fotograma de una película. Nuestra consciencia salta de un universo a otro de forma suave, es decir, dos universos estáticos adyacentes se parecerían mucho, porque solo existiría una diferencia infinitesimal entre ellos. El tiempo emerge pues cuando los diferentes universos transcurren a través de nuestra consciencia. Eso significa que nuestra consciencia, la de cada uno, solo puede existir transcurriendo por una única trayectoria. Cuando morimos, nuestra consciencia se disuelve definitivamente en el océano preconsciente del que procede. Todos nuestros recuerdos se pìerden entonces, algo así como el monólogo del replicante Roy Batty en Blade Runner :

… Yo he visto cosas que vosotros no creeríais. Atacar naves en llamas más allá de Orión. He visto rayos-C brillar en la oscuridad cerca de la Puerta de Tannhäuser. Todos esos momentos se perderán en el tiempo, como lágrimas en la lluvia. Es hora de morir

La interacción física de nuestra consciencia sobre cada uno de los universos estáticos produce cambios en ellos y en nosotros mismos, por lo que la trayectoria toma una nueva dirección (única), por cada interactuación. Esta teoría casi inverosímil, la cual roza más el esperpento que la razón, parece ser que tendría una característica muy interesante. Aunque no sabemos cuál sería el mecanismo universal por el cual lo que llamamos consciencia navegaría por el multiverso generando trayectorias irreversibles y únicas, podríamos decir que cada individuo con sintiencia, poseería libre albedrío, y eso implicaría que tal individuo podría tener la capacidad que influir en eventos singulares a su experiencia. ¿Qué es un evento singular?. Aquel acontecimientos que por su naturaleza es muy improbable que ocurra. Es decir, sería un intervalo de multiverso con probabilidad matemática muy cerca al cero. Pero. un individuo con sintiencia podría forzar, quizás mágicamente, la ocurrencia dentro de su tiempo vital, de uno de esos eventos singulares. ¿Cómo conseguiría hacer eso?. Pongamos un ejemplo: Supongamos que alguien desea que le toque el gordo de la lotería. Pero, cuando compra un billete de lotería sólo tiene 1/100000 de probabilidad de que le toque. Eso significa que tendría que estar comprando un billete cada día durante 100000 días = 273 años, para tener algo de probabilidad de que le toque alguna de esas veces. Lo bueno de la probabilidad es que si juegas puede tocarte a la primera, o nunca dentro de tu tiempo vital. Si te toca a la primera, o en un tiempo muy corto en comparación a esos 273 años, decimos que te ha ocurrido un evento singular. Algo que no es muy probable que ocurra, pero ocurrió. La consciencia de un individuo navegando por ese océano que es el multiverso, podría provocar la ocurrencias de eventos singulares.

Posted in Astrofísica, Cosmología, curiosidades y analogías | Tagged: , , , , , , , | Leave a Comment »

QUÉ ES UN JETA Y POR QUÉ HAY QUE CONDENARLO AL OSTRACISMO

Posted by Albert Zotkin on April 11, 2021

Un jeta es una piedra (Pedro Sánchez). Un jeta es un sociópata producto de la evolución darwiniana, un brote muy virulento producto del filtrado masivo de una vacuna antivírica llamada dignidad. Los jetas son arribistas, trepas de diversos pelajes. Sus características psicológicas más notables son la carencia de empatía, ego hipertrofiado, banalidad intelectual y emocional, y tropismo exacerbado de su organismo sésil hacia la mamandurria. Un jeta no es un pez, es un corcho, y como además es una piedra, podemos decir, con toda exactitud descriptiva, que un jeta es una piedra pómez., porque no posee mundo interior, el sustrato natural donde prospera es la superficie de cualquier sociedad humana. Cuando una excrecencia inguinal de esta clase se desprende del cuerpo de la dignidad, y sale a flote formando su propia jeta desde el genoma más profundo de la naturaleza porcina, el resto de los seres, que sí deben ser llamados propiamente humanos, quedan en riesgo de ser estafados, defraudados o simplemente manipulados. Cuando un jeta se acerque a ti y consigas, con mucha fortuna, que vuelva a haber distancia entre ambos, lo primero que debes comprobar es que tu cartera sigue intacta, y lo segundo es si empiezas a usar impropiamente la palabra democracia para referirte a cosas que son claramente antidemocráticas. Por todas estas razones, el ecosistema donde más prosperan estos organismos sésiles llamados jetas es la política, aunque también se les puede encontrar en otros sustratos, como reality shows donde suelen aparecer promoviendo crowfundings para sus causas, las cuales son siempre mentira.

Los jetas son autómatas, pero poseen unas destrezas altamente eficaces llamadas praxias mioeléctricas. Como todos sabemos, una praxia es el sistema de movimientos coordinados funcionalmente hacia un fin, resultado o intención. Pero en este subgénero de organismos inguinales llamados jetas, el fin predominante de estas praxias es siempre el mismo, el fin crematístico.

Cuando observas a un jeta de cerca y parece tener emociones básicas, como dolor, placer, o incluso alguna emoción algo más sofisticada como el éxtasis estético, casi todo es mentira, casi todo es fingido, simple y llanamente una burda simulación. Digo casi, porque los jetas sí poseen un conjunto real, no fingido de emociones, como la rabia, la ira o el odio desmedido al ser humano en general. Estos autómatas adoctrinados para la demagogia, el postureo, y la verborrea fácil y güera, son un peligro público, por eso hay que condenarlos al ostracismo. La gente falsa, emocional e intelectualmente fake, sobra en las sociedades humanas, aunque, todo hay que decirlo, estos especímenes son los que más prosperan, copando siempre las mejores plazas en la estructura sociopolítica. ¿Por qué ocurre esto?, ¿por qué estos organismos sésiles son siempre los que más éxito social tienen?. Se llama Principio de Peter. Elige al azar un inútil cualquiera, instalalo en cualquier estructura de poder o institucional. Al cabo de un tiempo, ese inútil termina ascendiendo hasta el nivel máximo de su propia incompetencia.

Saludos

Posted in Política, Sociedad | Tagged: , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

Relatos alienígenas: ʻOumuamua, el mensajero de Orión

Posted by Albert Zotkin on March 26, 2021

 
Hola amigos de Tardígrados . Hoy vamos a visitar un gigante. Se llama Betelguese, es una estrella local, también conocida como α Orionis.
 
 
Es la segunda estrella más brillante en luz visible de la Constelación de Orión, la primera es Rigel (β Orionis). Betelguese es una estrella supergigante roja, y su tamaño es tal que, si la pusiéramos en el lugar del Sol, su radio llegaría hasta el cinturón de asteroides, que como sabemos, se encuentra en una órbita intermedia entre la de Marte y la de Júpiter. Sus coordenadas celestes son [ascensión recta: 5 horas 55 minutos 10.30536 segundos, declinación: +07 grados 24 minutos 25.4304 segundos], y se encuentra a una distancia de 640 años-luz de nuestro sistema solar. Eso significa que, si viajáramos a una velocidad como la que tiene actualmente la sonda Voyager 1, tardaríamos en llegar a Betelguese unos 12 millones de años.
Os estaréis preguntando, “muy bien, viajar a una estrella supergigante roja está muy bien, pero ¿qué tiene de especial esa estrella que no tenga ninguna otra supergigante roja de las ‘infinitas’ que existen en nuestro universo?“.
Hace 12 millones de años, Betelguese empezó a agonizar, a morir. La forma de morir de aquella estrella, con una masa igual a 18 masas solares, es la de convertirse irremediablemente en una supergigante roja en poco tiempo. Poco tiempo son los 12 millones de años transcurridos hasta la fecha. Y desde hace 40 mil años ya quedó definitivamente convertida en supergigante roja. El objeto ʻOumuamua podría proceder de algún exoplaneta del sistema de Betelguese . Eso significa que dicho objeto posee una velocidad media de crucero de unas dos veces la velocidad de la sonda Voyager 1. Lamentablemente, no hemos inspeccionado in situ el mensajero de Orión, lo hemos dejado escapar con su valiosa carga. Ahora mismo escapa de nuestro sistema solar con una velocidad endiablada. Pero, gracias a Avi Loeb sabemos que es un objeto artificial metálico en forma de disco de color rojizo, de más de 200 metros de diámetro. Que parece ir a la deriva desde hace millones de años, y que hace unos 10 mil años ya estaba entrando por la Nube de Oort hacia el sistema Solar
Pero, ¿por qué ʻOumuamua sigue siendo considerado como candidato para ser un velero intergaláctico alienígena?. Según Avi loeb, en su libro Extraterrestrial: The First Sign of Intelligent Life Beyond Earth (Extraterrestre: Primer signo de vida inteligente más allá de la Tierra), existen seis hechos científicamente probados sobre nuestro invitado interestelar:
El 19 de Octubre de 2017, se descubrió el primer objeto interestelar, con del telescopio PanSTARRS, y fue localizado a una distancia de 1/6 UA, 25 millones de kilómetros del Sol, (1 Unidad Astronómica = 1 UA = distancia de la Tierra al Sol = 150 millones de km). La experiencia fue similar a encontrarse con un invitado sorpresa para cenar en nuestra mesa llegado de otro país. Examinando minuciosamente a nuestro invitado podemos saber cosas de su país de procedencia sin tener que viajar hasta allí para ello. En este caso, dada la inmensa distancia que nos separa de nuestro vecindario interestelar, nos costaría al menos más de cien mil años llegar hasta la estrella más próxima usando una nave lanzada mediante cohetes químicos convencionales. A continuación presentamos una lista de seis peculiaridades mostradas por `Oumuamua: Sorprendentemente, nuestro primer invitado interestelar resulta ser un objeto extraño y muy distinto a nada que hayamos visto antes. Cuando quisimos darnos cuenta, nuestro invitado ya estaba saliendo por la puerta, con su imagen desvaneciéndose en la oscuridad de la noche, por lo que no tuvimos una segunda oportunidad de echar un vistazo a sus misteriosas cualidades. 

 

  1. COBE_cmb_fluctuationsAsumiendo que otros sistemas estelares se parecen al Sistema Solar, PanSTARRS no debería haber descubierto ninguna roca interestelar. En un documento publicado hace una década, predecíamos una abundancia de asteroides interestelares menores por muchos órdenes de magnitud a lo que se necesita para explicar el descubrimiento de `Oumuamua como miembro de una población de objetos al azar. Es decir, la población interestelar de objetos es con mucho más grande de lo esperado. Cada estrella en la Vía Láctea necesitaría eyectar una media de 1014 objetos de esa clase durante su vida para poder explicar dicha población inferida, y eso es mucho más de lo que existe en el sistema solar. Por lo tanto, los viveros de objetos, como `Oumuamua deben ser muy distintos a los conocidos.
  2. COBE_cmb_fluctuations`Oumuamua se originó en un sistema de referencia muy peculiar, cerca del llamado Sistema de Reposo Local (LSR), el cual se define promediando los distintos movimientos al azar de todas las estrellas en la vecindad del Sol. Sólo una estrella de cada quinientas es tan lenta como `Oumuamua en ese sistema de referencia. El LSR es el sistema de referencia ideal para camuflarse. para esconder el origen de un objeto y evitar ser asociado con una estrella en concreto – ya que las estrellas típicamente se mueven en ese sistema de referencia. El movimiento relativo entre `Oumuamua y el Sol refleja el movimiento del Sol respecto al LSR. `Oumuamua sería como una boya que esté en reposo en la superficie del océano, y el sistema solar yendo hacia ella como si fuera un veloz velero. ¿Podría haber un conjunto de “boyas” que serviría como estaciones repetidoras, o señales de tráfico, que definirían el sistema de referencia galáctico promedio en el espacio interestelar?.
  3. COBE_cmb_fluctuationsEs de presumir que muchos asteroides interestelares se deshagan en pedazos a las afueras de sus sistemas planetarios (como en la Nube de Oort en el sistema Solar, la cual se encuentra unas 100 mil veces la distancia Tierra-Sol). En esas localizaciones tan alejadas de la influencia gravitacional de la estrella principal del sistema, esos cuerpos pueden ser desestabilizados muy fácilmente y lanzados al espacio interestelar a la mínima perturbación. Si la velocidad orbital de un objeto en esas nubes exteriores (como la de Oort) es perturbada por algo más de 1 km/s, escaparía gravitacionalmente del sistema hacia el espacio inter estelar, pero aún seguiría anclado globalmente en promedio a la velocidad de su sistema estelar respecto del LSR. Si `Oumuamua nos visitó procediendo de una estrella típica de nuestro vecindario debió escapar de su sistema porque sufrió un impulso inusual mucho más grande que el típico 1 km/s. Y para hacer las cosas aun más inusuales, ese impulso debería haber sido igual en magnitud y de sentido contrario a la velocidad de su estrella principal en su sistema estelar relativa al LSR, que es de unos veinte km/s para una estrella típica como el Sol. El origen dinámico de `Oumuamua es extraordinariamente raro, independientemente de como lo mires. Es sorprendente, porque el primer invitado extranjero a una cena debería ser estadisticamente común.
  4. COBE_cmb_fluctuationsNo tenemos una foto de `Oumuamu, pero su brillo debido al reflejo de la luz del Sol varía con un factor de 10, como si giras periódicamente cada ocho horas. Esto implica que `Oumuamua tiene una forma extrema, de una longitud entre 5 y 10 veces más larga que su ancho. Más aún, un análisis de su movimiento de volteo concluyó que tendría que estar en su máximo estado de excitación, como es de esperar de un viaje tan tumultuoso como el suyo, por lo que su forma debe ser como la de una tortita (pancake). Esa forma inferida es más extrema de la de cualquier otro asteroide visto previamente en el sistema solar, que tienen razones axiales (largo sobre ancho) de como mucho 3.
  5. COBE_cmb_fluctuationsEl Telescopio Espacial Spitzer no detectó ninguna fuente de calor en forma de radiación infrarroja procedente de `Oumuamua. Dada la temperatura superficial dictada por la trayectoria de `Oumuamua cerca del Sol, se establece un limite superior para su tamaño de cientos de metros. Si nos basamos en este limite de tamaño, `Oumuamua debería ser inusualmente brillante, con una refractancia de al menos diez veces más alta de la que se observa en los asteroides del sistema solar.
  6. COBE_cmb_fluctuationsLa trayectoria de `Oumuamua esta desviada de la que se espera debería tener si se moviera solo por la influencia del Sol. La variación es pequeña (un 0.1%), pero estadisticamente es muy significativa. Los cometas muestran esa desviación cuando el hielo de su superficie, al ser calentado por la radiación Solar y evaporarse, generan impulso por el llamado efecto cohete. El empuje extra.
El impulso que la órbita de `Oumuamua exhibe no pudo originarse debido a una posible desintegración en piezas del objeto, porque un evento tal le habría proporcionado un impulso muy distinto al del empuje continuo que se observó. Si descartamos emisiones de gas como las de los cometas, y el exceso de fuerza inferido es real, sólo nos queda una posibilidad – un empuje extra debido al viento solar. Para que ese empuje sea efectivo, `Oumuamua necesitaría tener un grosor menor a un milímetro, y una superficie de un tamaño de al menos veinte metros (para un reflector perfecto), con aspecto de una vela solar de origen artificial. En tal caso `Oumuamua se parecería a la vela solar propuesta en la misión japonesa IKAROS12, o la vela contemplada en la iniciativa Starshot. Un origen artificial nos ofrece la sobrecogedora posibilidad de que hemos descubierto un “mensaje dentro de una botella”. después de años de fracasos intentando escuchar señales de radio procedentes de civilizaciones extraterrestres. En resumen, una vela de esas características habría salido indemne de colisiones con partículas de polvo y átomos interestelares en su viaje a través de la galaxia.
Recientemente, dos astrofísicos de la Universidad Estatal de Arizona, Steven Desch y Alan Jackson, nos cuentan que ese objeto interestelar que hemos llamado ‘Oumuamua no es ninguna nave alienígena, sino que podría ser un objeto compuesto a base de nitrógeno sólido, y que sería un fragmento de un exoplaneta muy parecido al planeta Plutón: 
 
Sí, a todos nos gusta la idea romántica de que existan civilizaciones alienígenas con tecnología muy avanzada, y que alguna de ellas nos visite (espero que con intenciones pacíficas) y nos enseñen todas sus maravillosos gadgets. Pero, me da la impresión de que estos dos científicos tienen tantas pruebas en contra de la hipótesis de Avi Loeb, como este pueda tenerlas a favor. Lo que ocurre, es que Desch y Jackson se posicionan de forma supremacista en el lado mayoritario del mainstream, es decir, el lado del consenso general, y están en la creencia de que ellos son los que tienen la razón y todo el que intente defender una postura distinta está equivocado. Pero, como digo, lo que estos científicos sostienen es sólo una hipótesis más. Para demostrar cientificamente que ‘Oumuamua no es una nave alienígena, habría que enviar una sonda espacial que se aproximara al objeto, el cual escapa del sistema solar a gran velocidad.
 
Por su parte, Avi Loeb no ha tardado en responder a estos dos científicos diciendo que si el objeto ‘Oumuamua estuviera compuesto de hielo de nitrógeno también tendría que haber carbono, pero el Telescopio Espacial Spitzer no observó trazas de carbono Pioneer

 

Saludos

Posted in Astrofísica, Exobiología | Tagged: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | 2 Comments »

Cómo programar tu propio minero de bitcoins, y no morir en el intento

Posted by Albert Zotkin on March 23, 2021

Reinventar la rueda puede tener varios contratiempos o inconvenientes. El primero de ellos es que la rueda ya está inventada, así que sería aparentemente una pérdida de tiempo y otros recursos el tratar de inventar algo que ya existe. Sin embargo, podemos probar a reinventar cosas con el sólo propósito de aprender, es decir, para adquirir conocimiento técnico sobre un tema específico. El segundo contratiempo o inconveniente de reinventar la rueda es que podría resultar que tu rueda no fuera tan perfecta y redonda como las ya existentes en el mercado, con lo cual la funcionalidad de tu creación sería más bien una chapuza que algo útil. El tercer inconveniente es que, aunque consiguieras crear una rueda bastante redonda y util, podría quedar descolgada, ya que no habría un coche o carro donde instalarla para probarla y ver cómo trabaja. Es decir, te quedarías colgado de la brocha, porque te habrían quitado la escalera de pronto. Si, a pesar de todos los inconvenientes y gasto inútil de recursos de todo tipo, aún sigues empeñado en reinventar la rueda, entonces tu única opción es seguir adelante.

Vamos a ello. Lo primero que vamos a programar es un servidor que pondremos a la escucha en nuestro localhost por el puerto 3000, y con el que gestionaremos todo los relacionado con los mineros de Bitcoins: Altas, bajas, envío de tareas, comprobaciones varias, gestión de cobros y pagos. Nuestro servidor lo programaremos en Node.JS . Y este será nuestro script inicial: Lo llamaremos

server-pool.js

  1. const Net = require('net');
  2. const url = require('url');
  3. const bitcore = require('bitcore-lib');
  4. const Hash = bitcore.crypto.Hash;
  5. const BufferUtil = bitcore.util.buffer;
  6. const _ = require('./util');
  7. const prettify = require('../prettify.js')();
  8. const stdin = process.openStdin();
  9. const fs = require('fs');
  10. const users_file ='./user.json';
  11. const DT = require('./datatypes');
  12. const $ = require('./util');
  13. const get = require('./manageGetRequest');
  14. const MBP = require('./make-block-project');
  15. var t_url = url.parse('http://127.0.0.1:3000/');
  16. var port = t_url.port;
  17.  
  18. /*
  19. const options = {
  20.   key: fs.readFileSync('./openssl/key.pem'),
  21.   cert: fs.readFileSync('./openssl/cert.pem')
  22. };
  23. */
  24.  
  25. const server = new Net.Server();
  26. var chats = [];
  27. var current_chat = null;
  28. var current_block_project = null;
  29. var ids = 0;
  30. var users = JSON.parse(fs.readFileSync(users_file, function(err){
  31. if(err) throw(err);
  32. }));
  33.  
  34. const MAX_HISTORY_SIZE = 40;
  35. const QUORUM_PERCENT = 74; // //percentage of minimum number of miners to proceed mining
  36. var jobready_count = 0;
  37.  
  38.  
  39.  
  40. server.listen(port, function() {
  41. console.log('\x1b[36m\x1b[2m[Server listening for connection requests on socket\x1b[0m:');
  42. //console.log(users);
  43.  
  44. });
  45. stdin.addListener("data", function(d) {
  46.  
  47. /*
  48.   var sentence = d.toString().trim();
  49.   talkTo(sentence);
  50.   sanitizeChats();
  51.   */
  52.  
  53. var sentence = d.toString().trim();
  54. var line = sentence.split('>');
  55. var header = line[0];
  56. var body =line[1];
  57. switch (header){
  58. case 'stop':
  59. broadcast2All(DT.StopMessage());
  60. break;
  61. case 'new'://'new-block-project':
  62. MBP.startNewBlockProject(false); //true =>get actual data from blockchain.info
  63. break;
  64. case 'ping':
  65. if(current_chat)
  66. current_chat.socket.write(DT.PingMessage());
  67. else console.error({error:'no clients connected'});
  68. break;
  69. case 'broadcast':
  70. broadcast2All(DT.testMessage());
  71. break;
  72. case 'exit':
  73. console.log("\x1b[33m[Server is about to be closed]\x1b[0m");
  74. server.destroy();
  75. setTimeout(function(){ process.exit(0)}, 1000); // kill client
  76. break;
  77. case 'exit':
  78.  
  79. break;
  80. default:
  81.  
  82. talkTo(sentence);
  83. sanitizeChats();
  84.  
  85. break;
  86. }
  87.  
  88. });
  89.  
  90. server.on('connection', function(socket) {
  91. console.log('\x1b[36mA new connection has been established\x1b[0m.');
  92. //current_chat = setChat(socket);
  93. //talkTo();
  94. socket.on('data', function(chunk) {
  95. current_chat = setChat(socket);
  96. var msg = DT.readMessage(chunk);
  97. if(msg)talkFromMessage(msg);
  98. else {
  99. var sentence = chunk.toString().split('\n');
  100. var w = chunk.toString().split(' ');
  101. var word = w[0];
  102. switch(word){
  103. case 'GET':
  104. /*
  105.   current_chat.socket.write([
  106. 'HTTP/1.1 200 OK',
  107. 'Content-Type: text/html; charset=UTF-8',
  108. 'Content-Encoding: UTF-8',
  109. 'Accept-Ranges: bytes',
  110. 'Connection: keep-alive',
  111. ].join('\n') + '\n\n');
  112. current_chat.socket.write('<h1> Example </h1> <img src ="../uploads/building.jpg"> ');
  113. // console.log(sentence[0].split(' ')[1]);
  114. //current_chat.socket.end();
  115. */
  116. get.ManageGetRequest(chunk,socket)
  117. console.log(chunk.toString());
  118. break;
  119. default:
  120. talkFrom(chunk.toString());
  121. break;
  122. }
  123.  
  124. }
  125. });
  126.  
  127. socket.on('end', function() {
  128. current_chat = setChat(socket);
  129. console.log('\x1b[36m\x1b[2mClosing connection with the client %s\x1b[0m.',current_chat.user);
  130. removeChat(socket);
  131. current_chat = null;
  132. });
  133.  
  134. socket.on('error', function(err) {
  135. current_chat = setChat(socket);
  136. console.log(err);
  137. });
  138. });
  139.  
  140. function talkTo(message){
  141. if(current_chat){
  142. var msg = message;
  143. if(current_chat.user === 'anonymous' ){
  144. msg = '\x1b[32mHello, \x1b[1mUSER:PWD\x1b[0m\x1b[32m, please\x1b[0m'
  145. }
  146. if(msg){
  147. current_chat.socket.write(msg);
  148. current_chat.history.push(msg);
  149. }
  150. }
  151. }
  152.  
  153.  
  154. function talkFrom(message){
  155.  
  156. if(current_chat){
  157.  
  158. if(current_chat.user === 'anonymous'){
  159. var msg = message.split(':');
  160. if(msg.length == 2) checkUserPwd(msg,current_chat);
  161. talkTo();
  162. }
  163.  
  164. console.log('%s: \x1b[33m%s\x1b[0m',current_chat.user, message);
  165. current_chat.history.push(message);
  166. }
  167. }
  168.  
  169. function talkFromMessage(m){
  170.  
  171. if(current_chat){
  172.  
  173. if(current_chat.user === 'anonymous'){
  174. var msg = m.payload.toString('utf8').split(':');
  175. if(msg.length == 2) checkUserPwd(msg,current_chat);
  176. talkTo();
  177. }
  178. onCommand(m);
  179. var obj = {};obj[current_chat.user]= m;
  180. console.log(obj);
  181. current_chat.history.push(JSON.stringify(m));
  182. }
  183. }
  184. /*
  185. function checkUserPwd(msg, chat){
  186.  
  187.   for(var e in users){
  188.   if(msg[0] === e && msg[1] === users[e].pwd ){
  189.   for(var f in chats){
  190.   if(chats[f].socket == chat.socket){
  191.   chats[f].user = msg[0];
  192.   chat.socket.write('Thanks ' + chats[f].user);
  193.   return true;
  194.   }
  195.   }
  196.   }
  197.   }
  198. return false;
  199. }
  200. */
  201. function checkUserPwd(msg, chat){
  202.  
  203. for(var e in users){
  204. if(msg[0] === e && msg[1] === users[e].pwd){
  205. for(var f in chats){
  206. if(chats[f].user == msg[0]) return false;
  207. if(chats[f].socket == chat.socket){
  208. chats[f].user = msg[0];
  209. chat.socket.write('Welcome ' + chats[f].user);
  210. return true;
  211. }
  212. }
  213. }
  214. }
  215. return false;
  216. }
  217.  
  218. function sanitizeChats(){
  219.  
  220. for(var e in chats){
  221. if(chats[e].history.length > MAX_HISTORY_SIZE)
  222. chats[e].history.shift();
  223. }
  224. }
  225.  
  226. function setChat(socket){
  227.  
  228. var chat = {user:'anonymous',id :-1,socket:socket,history:[]};
  229.  
  230. for(var e in chats){
  231. if(chat.socket == chats[e].socket)
  232. return chats[e];
  233. }
  234. chat.id =ids++;
  235. chats.push(chat);
  236. return chat;
  237. }
  238. function resumeChat(user, socket){
  239.  
  240. var chat = {user:user, id:-1, socket:socket, history:[]};
  241. for(var e in chats){
  242. if(user == chats[e].user){
  243. chats[e].socket = socket;
  244. return chats[e];
  245. }
  246. }
  247. chat.id =ids++;
  248. chats.push(chat);
  249. return chat;
  250. }
  251. function removeChat(socket){
  252.  
  253. for(var e in chats){
  254. if(chats[e].socket == socket){
  255. chats.splice(e, 1);
  256. }
  257. }
  258.  
  259. }
  260.  
  261. function broadcast2All(message){
  262. if(chats)for(var e in chats){
  263. chats[e].socket.write(message);
  264. }
  265. }
  266.  
  267. function sendNoncePartition2All(){
  268. var size = chats.length;
  269. var a = getNoncePartition();
  270. var buf = new Buffer.alloc(8);
  271. if(chats)for(var e=0;e<size;e++){
  272. buf.writeUInt32BE(a[e],0); buf.writeUInt32BE(a[e+1],4);
  273. var nonce_p ={
  274. command: 'nonce_p',
  275. networkMagic: new Buffer.from('FF00FF00', 'hex'),
  276. payload: buf
  277. };
  278. var msg = DT.makeMessage(nonce_p);
  279.  
  280.  
  281. /*
  282. var msg2 = DT.readMessage(msg);
  283. var p = [
  284. msg2.payload.readUInt32BE(0),
  285. msg2.payload.readUInt32BE(4)
  286. ];
  287. console.log(msg2);
  288. */
  289. chats[e].socket.write(msg);
  290.  
  291. }
  292.  
  293. }
  294.  
  295. function getNoncePartition(){
  296.  
  297. var size = chats.length;
  298. const nonce = 0xffffffff;
  299. var p = Math.floor(parseFloat(nonce)/size);
  300. var b = [];
  301. for(var i = 0;i<size;i++){
  302. b.push(i*p);
  303. }
  304. b.push(nonce);
  305. return b;
  306.  
  307. //return_.SplitInterval([0,45676543],6));
  308. }
  309.  
  310.  
  311. function onCommand(msg){
  312. var command = msg.command;
  313. switch(command){
  314. case 'ping':
  315. current_chat.socket.write(DT.PongMessage(msg));
  316. break;
  317.  
  318. case 'joback':
  319. jobready_count++;
  320. if(jobready_count >= chats.length){
  321. jobready_count=0;
  322. sendNoncePartition2All();
  323. }
  324. break;
  325.  
  326. case 'block_solved':
  327. try{
  328. var file = 'solved-'+ Date.now()+'.hex';
  329. fs.writeFileSync(file,msg.payload.toString('hex'),'utf8');
  330. broadcast2All(DT.StopMessage());
  331. }catch(e){
  332. console.error(e);
  333. }
  334. break;
  335. /*
  336. case:
  337. break;
  338. case:
  339. break;
  340. case:
  341. break;
  342. */
  343.  
  344. }
  345. }
  346.  
  347.  
  348. MBP.emitter.on('new-block-project-ready', () => {
  349.  
  350. console.log('\x1b[33mnew-\x1b[1mblock-project\x1b[0m\x1b[33m-ready:\x1b[0m');
  351. current_block_project = new bitcore.Block.fromBuffer(MBP.get_block_project());
  352. console.log(current_block_project.header.toObject());
  353. broadcast2All(DT.JobMessage(current_block_project.header.toBuffer()));
  354.  
  355.  
  356.  
  357. });
  358.  
  359.  
Los módulos requeridos net, bitcore-lib y url, los instalaremos mediante npm . Los restantes módulos requeridos son scripts que deberemos escribir nosotros, y son los siguientes:

util.js

  1. 'use strict';
  2. const bitcore = require('bitcore-lib');
  3. const Random = bitcore.crypto.Random;
  4. var $ = bitcore.util.preconditions;
  5. const BufferReader = bitcore.encoding.BufferReader;
  6. const BufferWriter = bitcore.encoding.BufferWriter;
  7. const OUTPUT = 1;
  8. const INPUT = 0;
  9. /*
  10. Can parse a JSON object even if there are comment tags between its items
  11. */
  12. var parseW = function(str){
  13. return JSON.parse(str.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1'));
  14. }
  15.  
  16.  
  17. function variantToBufferFromNum(n){
  18. return new BufferWriter(new Buffer.alloc(0))
  19. .writeVarintNum(n)
  20. .toBuffer();
  21. }
  22.  
  23. function SplitInterval(partition,n){
  24.  
  25. if(typeof partition !== 'object') return null;
  26. if(typeof partition[0] !== 'number' ||
  27. typeof partition[1] !== 'number') return null;
  28. if( partition[1] - partition[0] <= 0) return null;
  29. var d = Math.floor((partition[1]-partition[0])/n);
  30.  
  31. var b = [];
  32.  
  33. for(var j = 0;j<n;j++){
  34. var c = [];
  35. c.push(partition[0] + d*j);
  36. c.push(partition[0] + d*(j+1)-1);
  37. b.push(c);
  38. }
  39.  
  40. b[n-1][1] = partition[1];
  41. return b;
  42. }
  43.  
  44. function format_date(timestamp){
  45. var date = new Date(timestamp * 1000);
  46. var day = date.getDate();
  47. //var month = months_arr[date.getMonth()];
  48. var month = date.getMonth()+1;
  49. var year = date.getFullYear();
  50.  
  51. var hours = date.getHours();
  52. var minutes = "0" + date.getMinutes();
  53. var seconds = "0" + date.getSeconds();
  54. // Will display time in 10:30:23 format
  55. var formattedTime = month + '/' + day + '/' +year +
  56. ' ' + hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
  57. return formattedTime;
  58. }
  59.  
  60. /*
  61. split buffer buf into an array of subbuffers,
  62. separator must be a string of bytes in hexadecimal mode.
  63. */
  64. function Split(buf, separator){
  65. var occurr =[];
  66. var sp =[];
  67. var b = new Buffer.from(buf);
  68. var pos = 0;
  69. var i = 0;
  70. const magic = new Buffer.from(separator, 'hex');
  71. while(1){
  72. var index = b.indexOf(magic);
  73. if(index > -1){
  74. pos += index;
  75. occurr.push(pos+magic.length*i);i++;
  76. b = b.slice(index+magic.length);
  77. }else break;
  78. }
  79. if(occurr.length){
  80. if(occurr[0]>0)
  81. sp.push(buf.slice(0,occurr[0]));
  82. for(var i = 0;i<occurr.length;i++)
  83. sp.push(buf.slice(occurr[i],occurr[i+1]));
  84. /*if(occurr[occurr.length-1]< buf.length-1)
  85. sp.push(buf.slice(occurr[occurr.length-1]));*/
  86. } else sp.push(buf);
  87.  
  88. return sp;
  89. }
  90.  
  91. Buffer['split'] = Split; //let Global Object, Buffer, manages this.
  92. JSON['parseW'] = parseW; //let Global Object, JSON, manages this.
  93.  
  94.  
  95. function WM_Encrypt(buffer, mode){
  96. if(buffer.length){
  97. var puntero = 0;
  98. var size = buffer.length;
  99. while(puntero < size/2)
  100. {
  101. Traspuesta(puntero,size-puntero-1,mode,buffer);
  102. puntero++;
  103. }
  104. }
  105.  
  106. return buffer;
  107. }
  108. function Traspuesta(i, j, modo, buffer){
  109.  
  110. var nparam1,nparam2;
  111. nparam1 = buffer.readUInt8(i);
  112. if(modo)nparam1 = nparam1 - 10;
  113. else nparam1 = nparam1 + 10;
  114. nparam1 = nparam1<0?256+nparam1:nparam1;
  115. nparam1 = nparam1>0xff?nparam1-256:nparam1;
  116. nparam2 = buffer.readUInt8(j);//flujofichero.charCodeAt(j);
  117. if(modo)nparam2 = nparam2 - 10;
  118. else nparam2 = nparam2 + 10;
  119.  
  120. nparam2 = nparam2<0?256+nparam2:nparam2;
  121. nparam2 = nparam2>0xff?nparam2-256:nparam2;
  122. buffer.writeUInt8(nparam2, i);
  123. buffer.writeUInt8(nparam1, j);
  124. }
  125.  
  126. function wm_encode(buffer){
  127. return WM_Encrypt(buffer, OUTPUT);
  128. }
  129. function wm_decode(buffer){
  130. return WM_Encrypt(buffer, INPUT);
  131. }
  132.  
  133. function stochash256(buffer){
  134. if(buffer.length !== 256) return null;
  135. var pt =0;
  136. var hash = []
  137. while(1){
  138. var byte = buffer.readUInt8(pt);
  139. var repunit = getRepunit(byte);
  140. var rnd = Random.getRandomBuffer(1).readUInt8(0);
  141. hash.push(repunit[rnd]);
  142. pt++;
  143. if(pt == buffer.length)break;
  144. }
  145. var result = new bitcore.crypto.BN.fromString(hash.join(''),2);
  146. return result.toBuffer();
  147. }
  148. function getRepunit(byte){
  149.  
  150. const two = new bitcore.crypto.BN(2);
  151. const one = new bitcore.crypto.BN(1);
  152. var b = new bitcore.crypto.BN(byte);
  153. var repunit = two.pow(b);
  154. repunit = repunit.sub(one);
  155. return repunit.toString(2,256);
  156.  
  157.  
  158. }
  159.  
  160. module.exports =
  161. {
  162. SplitInterval:SplitInterval,
  163. variantToBufferFromNum:variantToBufferFromNum,
  164. format_date:format_date,
  165. WM_Encrypt:WM_Encrypt,
  166. wm_encode:wm_encode,
  167. wm_decode:wm_decode,
  168. stochash256:stochash256,
  169. getRepunit:getRepunit
  170. };
  171.  
¿Aún no has perdido la ilusión por reinventar la rueda?. Ok, sigamos pues escribiendo los scripts para nuestros módulos requeridos

Posted in Bitcoin, criptografía, Criptomonedas, curiosidades y analogías, informática, Satoshi | Tagged: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a Comment »

 
%d bloggers like this: