Artoria2e5 / PRCoords

Public Domain library for rectifying Chinese coordinates

Home Page:https://artoria2e5.github.io/PRCoords/demo.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Making Protest Code Snippets, Artworks and T-shirts

biergaizi opened this issue · comments

It would be helpful to make some protest code snippets, artworks, T-shirts that are easy to express and reproduce the core algorithm of the transformation of coordinates, i.e something like RSA in CrytoWar, DeCSS in DVD, or Free Speech Flag in Blu-ray. It also makes the act of activism more interesting to participate.

Perl program:

$_='while(read+STDIN,$_,2048){$a=29;$b=73;$c=142;$t=255;@t=map{$_%16or$t^=$c^=(
$m=(11,10,116,100,11,122,20,100)[$_/16%8])&110;$t^=(72,@z=(64,72,$a^=12*($_%16
-2?0:$m&17)),$b^=$_%64?12:0,@z)[$_%8]}(16..271);if((@a=unx"C*",$_)[20]&48){$h
=5;$_=unxb24,join"",@b=map{xB8,unxb8,chr($_^$a[--$h+84])}@ARGV;s/...$/1$&/;$
d=unxV,xb25,$_;$e=256|(ord$b[4])<<9|ord$b[3];$d=$d>>8^($f=$t&($d>>12^$d>>4^
$d^$d/8))<<17,$e=$e>>8^($t&($g=($q=$e>>14&7^$e)^$q*8^$q<<6))<<9,$_=$t[$_]^
(($h>>=8)+=$f+(~$g&$t))for@a[128..$#a]}print+x"C*",@a}';s/x/pack+/g;eval

CryptoWar RSA Protest T-shirt

Free Speech Flag

Favicon:

wget http://decss.zoy.org/favicon.ico
dd dd if=favicon.ico skip=2238 bs=1

Idea: embed the icon in the favicon of PRCoords

DeCSS Haiku:

All we have to do
is this: copy our DKEY
into im1,

use the rule above
that decrypts a disk key (with
im1 and its

friend im2 as
inputs) -- thus we decrypt the
disk key im1.

"So this number is,
once again, the player key:
(trade secret haiku?)

"Eighty-one; and then
one hundred three -- two times; then
two hundred (less three)

two hundred twenty
four; and last (of course not least)
the humble zero."

Once you have your artwork, it is easy to submit it to Redbubble for making and selling it automatically.

A "not quite code" transcription of the forward algo is available at https://www.wikidata.org/wiki/Q29043602. I guess that can be something to start with?

Condensed the forward ops, 37lines×56cols (CC0 as usual):

(EDIT: just debugged it, so it's all 58col for now)

/**
* MiniPRCoords. Public Domain.
* WGS → GCJ → BD
* (35, 105) → (34.999093, 105.003286) → (35.005398, 105.009667)
* (34, 106) → (33.998424, 106.003994) → (34.004217, 106.010579)
* https://github.com/Artoria2e5/PRCoords */
let {sqrt, abs, sin, cos, hypot, atan2, PI} = Math

function wgs_to_gcj({lat, lon}) {
  /* 常数 / Constants: */
  let A  = 6378245            // Krasovsky 1940/SK-42: a
  let _F = 1 / 298.3          // Krasovsky 1940/SK-42: f
  let EE = 2*_F - _F**2       // e^2 = 2*f - f^2

  /* 偏移 / Shifts: */
  // noise origin: (35, 105); default shift: <300, -100>
  let y = lat - 35,  x = lon - 105
  let spi = ((z) => sin(z*PI))
  let Δ_N = -100+2*x+3*y+0.2*y*y+0.1*x*y+0.2*sqrt(abs(x))
            +20/3*(2*spi(6*x)+2*spi(2*x)+2*spi(y)
                  +4*spi(y/3)+16*spi(y/12)+32*spi(y/30))
  let Δ_E =  300+1*x+2*y+0.1*x*x+0.1*x*y+0.1*sqrt(abs(x))
            +20/3*(2*spi(6*x)+2*spi(2*x)+2*spi(x) 
                  +4*spi(x/3)+15*spi(x/12)+30*spi(x/30))

  /* 经纬 / Lat-lon packing: */
  let lat_r  = lat * PI / 180
  let common = 1 - EE * sin(lat_r)**2

  // meter → °
  let lat1 = (PI / 180) * (A * (1 - EE))   * common**1.5
  let lon1 = (PI / 180) * (A * cos(lat_r)) / common**0.5

  return {lat: lat + Δ_N/lat1, lon: lon + Δ_E/lon1}
}

let B_F = 3000/180*PI
let B_DLAT = 0.0060, B_DLON = 0.0065

function gcj_to_bd({lat, lon}) {
  let r = hypot(lat, lon) + 2e-5 * sin(B_F * lat)
  let θ = atan2(lat, lon) + 3e-6 * cos(B_F * lon)

  return {lat: r*sin(θ) + B_DLAT, lon: r*cos(θ) + B_DLON}
}

df = (a, b) => ({lat: a.lat - b.lat, lon: a.lon - b.lon})
function gcj_to_wgs(a) {
  return df(a, df(wgs_to_gcj(a), a))
}

function bd_to_gcj(a) {
  let {lat, lon} = df(a, {lat: B_DLAT, lon: B_DLON})
  let r = hypot(lat, lon) - 2e-5 * sin(B_F * lat)
  let θ = atan2(lat, lon) - 3e-6 * cos(B_F * lon)

  return {lat: r*sin(θ), lon: r*cos(θ)}
}

itery = (fwd, rev) => function(bad) {
  let curr = rev(bad)
  let prev = bad
  let diff = {lat: Infinity, lon: Infinity}

  while (abs(diff.lat) > 1e-5 || abs(diff.lon) > 1e-5)  {
    diff = df(fwd(curr), bad)
    prev = curr
    curr = df(curr, diff)
  } 

  return curr
}

I guess I will get it slightly syntax highlighted. Function names and comments should be emphasized so they look like section titles.

I don't quite feel like expressing the gcj and iterative backward ones in JS. Some formalae should do.

Fits on an A4 at unknown size too. The attachment sure looks ugly, but hey you got something to give to friends now!
https://commons.wikimedia.org/wiki/File:PRcoords_Cheatsheet.pdf

Ayy. I… uploaded this thing to… teespring. You can get a tote bag, a mug, or a sticker. https://teespring.com/miniprcoords-tote-v1

i still dont think the current code fits well on a t-shirt and i have no good idea how it will.

the manual version minifies to ~1100 characters with variable renaming and other uglyfied things, which is around twice the length of the perl thing. so.. 11 lines of garbage or 37 lines of loose small text?

🤔

I was thinking about some possible ways to eliminate the huge chunk of code on its nonlinear transformation by, e.g. extracting constants or making a lookup-table, but it seems the idea doesn't work well, not to mention the understandability of the code should be a focus. Is using a language with higher-level builtin math operations (Mathematica? Maple? Sage? Julia? Octave?) can help simplifying it? 🤔

For example, the Matlab code looks considerably shorter. https://github.com/Artoria2e5/PRCoords/blob/master/matlab/PRCoords.m Avoid coding high-level transformation in the code should help I guess, if the external function performs a well-known operation, it shouldn't be much of a problem.

I… don't think the MATLAB code is shorter than the js.

and OH FUCK THE CAIJUN ITERATION SHOULD BE A DO WHILE