แปลงสตริงของอักขระไบนารีให้เทียบเท่า ASCII


27

ใช้สตริงของอักขระไบนารีคั่นด้วยเว้นวรรคและแปลงเป็นสตริง ASCII

ตัวอย่างเช่น...

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

จะแปลงเป็น ...

Hello World

sสตริงไบนารีจะถูกเก็บไว้ในตัวแปรที่เรียกว่า

นี่เป็นความท้าทายของนักกอล์ฟที่จะได้ทางออกที่สั้นที่สุด


15
+1 สำหรับการท้าทายที่ไม่มีเนื้อเรื่องและคนใจแคบอื่น ๆ ตรงประเด็น
bebe

9
@bebe สัตว์เดรัจฉานที่แปลกประหลาดแบบฟอร์มครึ่งสนุก
qwr

สวัสดี. ลองจินตนาการว่าเทคโนโลยีของคุณล้ำหน้าไปมากจนไม่รองรับ ASCII มันจะได้รับอนุญาตให้แปลงเป็นการเข้ารหัสอักขระดั้งเดิมหรือจะต้องแปลง ASCII เป็นการเข้ารหัสอักขระดั้งเดิมหรือไม่ ฉันกำลังคิดZX81ที่นี่
Shaun Bebbers

คำตอบ:


10

ทับทิม, 36 32

s.split.map{|x|x.to_i(2).chr}*""

หรือ 31

s.gsub(/\w+ ?/){$&.to_i(2).chr}

การเพิ่มประสิทธิภาพต้องขอบคุณ Chron


1
คุณสามารถใช้แทน.join""สำหรับ*""การบันทึกตัวอักษรไม่กี่ คุณสามารถทำได้ด้วย gsub แทนที่จะแบ่ง + map + เข้าร่วมเช่น: s.gsub(/\w+ ?/){$&.to_i(2).chr}(31 ตัวอักษร)
Paul Prestidge

2
s.gsub(/\d+./){$&.to_i(2).chr}ได้ผลและเป็น 30 ตัวอักษรฉันไม่รู้ว่าทำไมมันถึงใช้ได้ .ไม่ควรตรงกับเวลาที่ผ่านมา แต่มันก็ไม่
addison

10

JavaScript (ES6) 49 55 56 64

s.replace(/\d+./g,x=>String.fromCharCode('0b'+x))

แก้ไขยอมรับคำแนะนำ @bebe - ขอบคุณ
Edit2ไม่ทราบเกี่ยวกับตัวอักษรตัวเลขไบนารี - ขอบคุณ @kapep
Edit3ว้าว 6 ไม่ใช่ 4ไบต์บันทึก thx @ETHproductions

คำอธิบายตามที่ร้องขอในความคิดเห็น

String.replace สามารถรับ 2 อาร์กิวเมนต์:

  • นิพจน์ทั่วไป/\d+./g: หนึ่งหลักหรือมากกว่าตามด้วยอักขระอื่น - แฟล็ก g ระบุเพื่อค้นหารูปแบบมากกว่าหนึ่งครั้ง
  • ฟังก์ชั่นที่ระบุไว้ที่นี่ในรูปแบบลูกศรที่อาร์กิวเมนต์ (x) จะเป็นสตริงที่พบ (ลำดับของตัวเลขในที่สุดตามด้วยช่องว่าง) และค่าของฟังก์ชั่นคือสิ่งที่ถูกแทนที่ (ในกรณีนี้ตัวละครเดียวจาก รหัส).

เป็นที่น่าสังเกตว่าในตอนท้ายของสตริงนั้น regexp ตรงกับลำดับของตัวเลขโดยไม่มีช่องว่างท้ายในกรณีนี้จุดจะตรงกับหลักสุดท้าย ลอง '123'.match (/ (\ d +) ./) เพื่อยืนยัน

(ยัง) อีกหนึ่งชิ้น verbose ของจาวาสคริปต์ที่เคย ...
(การกำหนดให้กับสตริง s ไม่นับ)

var s='1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
var x=
s.replace(/\d+./g,x=>String.fromCharCode('0b'+x))

console.log(x)


2
s.replace(/\d+./g,x=>String.fromCharCode(parseInt(x,2)))56
bebe

2
s.replace(/\d+./g,x=>String.fromCharCode(eval("0b"+x)))55
kapex

คุณช่วยอธิบายสิ่ง/\d+./g,x=>นี้ได้ไหม
izlin

1
@izlin ฉันได้เพิ่มคำอธิบายลงในคำตอบแล้ว
edc65

ฉันรู้ว่านี้เป็นคำตอบที่เก่า แต่คุณสามารถเปลี่ยนeval('0b'+x)ไป'0b'+x-0เพื่อประหยัด 4 ไบต์
ETHproductions

8

Bash + linux ทั่วไป utils 25 ไบต์

dc<<<2i$s[Pz0\<m]dsmx|rev

คำอธิบาย dc

  • ผลัก 2 ไปที่กอง; ป๊อปและใช้เป็น Radix อินพุต
  • กดสตริงป้อนเข้าเพื่อสแต็ค (ค่าทั้งหมดในครั้งเดียว)
  • กำหนดแมโครแบบเรียกซ้ำmไปที่:
    • pop จากนั้นพิมพ์ค่าเป็น ASCII
    • ผลักความลึกของกองซ้อนเพื่อกอง
    • กด 0 เพื่อสแต็ก
    • ป๊อปอัพ 2 ค่าสแต็ค; เปรียบเทียบและเรียกmแมโครถ้าสแต็กไม่ว่างเปล่า
  • สำเนาด้านบนสุดของสแต็ก (นิยามแมโคร)
  • ป๊อปและบันทึกมาโครเพื่อmลงทะเบียน
  • ป๊อปและเรียกใช้แมโคร

เนื่องจากเรากดทั้งไบนารีสตริงไปที่สแต็กก่อนเมื่อเราแสดงแต่ละค่าเราจึงสิ้นสุดด้วยการย้อนกลับสตริง ดังนั้นเราจึงใช้revโปรแกรมอรรถประโยชน์นี้เพื่อแก้ไข

ตัวอย่างการใช้งาน:

$ s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
$ dc<<<2i$s[Pz0\<m]dsmx|rev
Hello World
$ 

7

PowerShell, 49

-join(-split$s|%{[char][convert]::toint32($_,2)})

แก้ไข: ไม่เห็นคำตอบ PowerShell อื่น ๆ แต่มีวิธีเดียวเท่านั้นที่จะแก้ปัญหานี้


7

C - 57 43 38/31

รุ่น 38 ไบต์:

for(int*x=s;putchar(strtol(x,&x,2)););

หรือ 31 ไบต์เท่านั้นหาก s เป็นตัวชี้:

while(putchar(strtol(s,&s,2)));

ฉันไม่คิดว่ามันจะเป็นไปได้อย่างไรและในขณะที่ลูปควรจะใช้ ... แต่ใช้งานได้


6

Pyth , 12

smCv+"0b"dPZ

โปรดทราบว่า s ไม่ใช่ตัวแปรทางกฎหมายใน Pyth ดังนั้นฉันจึงใช้ Z แทน

คำอธิบาย:

        print(
s             sum(
m                 map(lambda d:
C                     chr(
v                         eval(
+"0b"d                         "0b"+d)),
P                     split(
Z                           Z))))

ตัวอย่าง:

=Z"<the binary string from above>"smCv+"0b"dPZ
Hello World

ความจริงมันไม่ได้ใช้ช่องว่างในการจัดรูปแบบ (นี่ดูคุณ Python) เป็น +1 ที่สำคัญ
Pharap

@Phapap Yeah, วิธีหนึ่งในการดู Pyth ก็คือ Python ที่มีองค์ประกอบทั้งหมดที่ทำให้ตัวละครถูกลบออกมากขึ้นเช่นช่องว่าง, วงเล็บ, โทเค็นหลายตัวละคร ฯลฯ
isaacg

ฉันไม่รู้จัก Pyth แต่จะไม่บันทึกอักขระ 4 ตัวเพื่อใช้id2แทนv+"0b"dหรือไม่ ไม่ว่าในกรณีใด ๆ นี่เป็นทั้งที่อ่านไม่ได้และยอดเยี่ยม
DLosc

@DLosc ฉันเพิ่มฟังก์ชั่นนั้นไปยัง Pyth หลังจากที่คำถามนี้ถูกถามส่วนใหญ่เนื่องจากคำถามนี้ มันจะสั้นลงด้วย Pyth ปัจจุบัน แต่ไม่อนุญาตให้ใช้ Pyth วันปัจจุบันสำหรับความท้าทายนี้
isaacg

ฉันเห็น. ฉันสงสัยว่ามันอาจเป็นแบบนั้นหรือเปล่า
DLosc

6

รหัสเครื่อง x86 บน DOS - 22 ไบต์

00000000  30 d2 b4 08 cd 21 2c 30  72 06 d0 e2 08 c2 eb f2  |0....!,0r.......|
00000010  b4 02 cd 21 eb ea                                 |...!..|

เนื่องจากไม่มีตัวแปรสตริงจริงในรหัสเครื่อง (และโดยเฉพาะอย่างยิ่งไม่มีตัวแปรชื่อ " s") ฉันตัดสิน stdin เป็นอินพุต

อินพุต NASM:

    org 100h

section .text

start:
    xor dl,dl
loop:
    mov ah,8
    int 21h
    sub al,'0'
    jb print
    shl dl,1
    or dl,al
    jmp loop
print:
    mov ah,2
    int 21h
    jmp start

6

Powershell ( 52 49)

-join(-split$s|%{[char][convert]::ToInt16($_,2)})

วนรอบง่ายกว่าสตริงไบนารีใน $ s ต้องรวม [แปลง] ฆ่าคะแนนของฉันแม้ว่า

แก้ไข: มีวิธีเดียวเท่านั้นที่จะดึงสิ่งนี้ออกใน Powershell, wowie Joey และฉันต่างก็มีคำตอบเดียวกันกับที่ทำงานอย่างอิสระมาก!

การป้อนข้อมูล:

1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100

เอาท์พุท:

Hello World

1
คุณสามารถใช้โอเปอเรเตอร์แบบแยกส่วนบันทึกตัวละครสามตัว (ตรงจุดที่คำตอบของเราเหมือนกัน ... แปลกใจใหญ่ ;-))
Joey

@ Joey Ohh จุดดี! ไม่อยากเชื่อเลยว่าฉันพลาดไป คุณได้รับ +1 จากฉันเนื่องจากการจับต้องขอบคุณ!
fuandon


5

Perl 33 32

แก้ไข: โซลูชันที่อัปเดต, 32.

say$s=~s/\d+ ?/chr oct"0b$&"/rge

โซลูชันก่อนหน้า (33):

$_=$s;say map{chr oct"0b$_"}split

หรือ

say map{chr oct"0b$_"}split/ /,$s

ทดสอบ:

perl -E '$s="1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100";$_=$s;say map{chr oct"0b$_"}split'

5

J (23)

u:;(#.@:("."0))&.>cut s

ทดสอบ:

   s=:'1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
   u:;(#.@:("."0))&.>cut s
Hello World

คำอธิบาย:

                  cut s    NB. split S on spaces
   (          )&.>         NB. for each element
        ("."0)             NB. evaluate each character
      @:                   NB. and
    #.                     NB. convert bitstring to number
  ;                        NB. unbox each number
u:                         NB. convert to ASCII



4

APL (15)

⎕UCS{2⊥⍎¨⍕⍵}¨⍎s

ทดสอบ:

      s←'1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100'
      ⎕UCS{2⊥⍎¨⍕⍵}¨⍎s
Hello World

คำอธิบาย:

  • ⍎s: ประเมินค่าsเปลี่ยนเป็นอาร์เรย์ของจำนวนเต็ม อาร์เรย์จะถูกเขียนเป็นตัวเลขคั่นด้วยช่องว่างดังนั้นการแบ่งsนี้
  • {... : สำหรับแต่ละองค์ประกอบ:
    • ⍕⍵: เปลี่ยนตัวเลขกลับเป็นสตริง
    • ⍎¨: ประเมินแต่ละหลักของแต่ละคนให้ bitstring
    • 2⊥: ถอดรหัสฐาน 2 ให้ตัวเลข
  • ⎕UCS: รับตัวอักษรสำหรับแต่ละหมายเลข

ยกเว้นที่ระบุไว้มิฉะนั้นคุณควรนับไบต์แทนของตัวอักษร: codegolf.stackexchange.com/tags/code-golf/info :)
Averroes

1
@Averroes: ชุดอักขระ APL มีขนาดเป็นไบต์พร้อมที่ว่าง: frankenstein.dns.org.uk/~marinus/aplcharset.png
marinus

อ่าฉันไม่รู้ ความผิดฉันเอง. ขออภัย!
Averroes

4

PHP (61)

<?=join(array_map('chr',array_map('bindec',explode(' ',$s))))

foreach(str_split($s,8)as$v)echo chr(bindec($v));
JörgHülsermann

@ JörgHülsermannการเข้ารหัสอาจข้ามเลขศูนย์นำหน้าดังนั้นstr_split($s,8)จะไม่ทำงาน foreach(explode(' ',$s)as$v)echo chr(bindec($v));จะใช้ได้ แต่ฉันไม่ได้วางแผนที่จะแก้ไขหนึ่งในคำตอบ PPGC แรกของฉันที่เห็นได้ชัดว่าไม่ได้เล่นกอล์ฟจริงๆ ขอบคุณอยู่ดี!
Christoph

4

แบคคัสขนาด 25 ไบต์

S,' 'j:A=(Ö,2,10b:c),A¨

คำอธิบาย:

S,' 'j แยก String S ด้วยพื้นที่ว่างและแปลงเป็นบล็อก

:A= รับ Block ก่อนหน้าและยืนยันกับตัวแปร A

(),A¨ สำหรับแต่ละองค์ประกอบใน A

Ö,2,10bอ่านองค์ประกอบปัจจุบัน (แสดงโดยÖ) ในฐาน 2 และแปลงเป็นฐาน 10

:c รับค่าก่อนหน้าและพิมพ์เป็นอักขระ



3

C - 63

เนื่องจาก C ไม่มีตัวแปลงฐาน 2 ในไลบรารีมาตรฐาน: ทดสอบที่นี่
แก้ไข: ใช่ฉันแค่โง่เกินกว่าจะรู้เกี่ยวกับมัน

r;f(char*s){for(;*s;(*s|32)-32||(putchar(r),r=0))r=2*r|*s++&1;}

3

Run Length Encoded Brainfuck, 49 ไบต์

เนื่องจากไม่มีตัวแปรใน Brainfuck ฉันจึงใช้อินพุตและเอาต์พุตมาตรฐานแทน

รหัส32+ควรถูกตีความเป็น 32 +วินาทีโดยล่าม เพียงแทนที่ด้วยตนเองหากล่ามของคุณไม่รองรับ RLE

>,[32->+<[16-<[>++<-]>[<+>-]>-<]>[<<.[-]>>-]<,]<.

รุ่นที่ขยาย (ไม่ใช่ RLE): (91 ไบต์)

>,[-------------------------------->+<[----------------<[>++<-]>[<+>-]>-<]>[<<.[-]>>-]<,]<.

รหัสจะถือว่า EOF ถูกเข้ารหัสเป็น 0

คำอธิบาย

ใช้เค้าโครงต่อไปนี้:

+---+---+------+
| x | a | flag |
+---+---+------+

โดยxที่ ASCII ไบต์ที่จะพิมพ์aคืออักขระจากอินพุตมาตรฐานและflagคือ 1 ถ้าaเป็นช่องว่าง

>,            Read a character a into the second cell
[             While not EOF: 
  32-           Decrease a by 32 (a -= ' ')
  >+<           Set the flag to 1 
  [             If a was not a space:
    16-           Decrease by 16 more ('0' == 32+16)
    <[>++<-]      a += 2*x
    >[<+>-]       Move it back (x = a)
    >-<           Reset the flag, it was not a space.
  ]>
  [             If a was a space (flag == 1):
    <<.[-]        Print and reset x
    >>-           Reset the flag
  ]
  <,            Read the next caracter a
]
<.            Print the last character x

1
+1 เพราะทุกอย่างควรมีการนำสมองมาใช้
Pharap

"Run Length Encoded Brainfuck" เป็นภาษาที่แยกกันจริงหรือ ฉันหาล่ามไม่ได้
mbomb007

3

Java 8: 60 ไบต์

การใช้ lambdas ใน Java 8 (75 ไบต์):

Arrays.stream(s.split(" ")).reduce("",(a,b)->a+(char)Byte.parseByte(b,2));

และถ้าคุณอนุญาตการนำเข้าแบบคงที่ (ซึ่งบางส่วนใช้ที่นี่) ก็คือ (61 ไบต์):

stream(s.split(" ")).reduce("",(a,b)->a+(char)parseInt(b,2))

เวอร์ชันที่สั้นกว่าเล็กน้อยใช้สำหรับลูป (60 ไบต์):

for(String n:s.split(" ")){out.print((char)parseInt(n,2));}

2
สิ่งที่พวกเขาทำแทนความน่ากลัวที่รู้จักกันในชื่อคลาสที่ไม่เปิดเผย? น่ากลัว
seequ

@Sieg ใช่ Java มี lambdas / ปิดในขณะนี้เช่นกัน แต่ส่วนใหญ่จะเป็นน้ำตาลสังเคราะห์ด้านบนของชั้นเรียนที่ไม่ระบุชื่อ ... (ชัด)
รอยรถตู้ Rijn

3

Clojure 63 (หรือ 57)

All-Clojure impl:

(apply str(map #(char(read-string(str"2r"%)))(re-seq #"\d+"s)))

ด้วย Java interop:

(apply str(map #(char(Long/parseLong % 2))(.split s" ")))

เซสชัน REPL:

golf> (def s "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100")
#'golf/s
golf> (apply str(map #(char(read-string(str"2r"%)))(re-seq #"\d+"s)))
"Hello World"
golf> (apply str(map #(char(Long/parseLong % 2))(.split s" ")))
"Hello World"

3

QBasic, 103

s$=s$+" ":FOR i=1 TO LEN(s$):c$=MID$(s$,i,1):IF c$=" "THEN n=0:r$=r$+CHR$(n)ELSE n=n*2+VAL(c$)
NEXT:?r$

อะไร? เราไม่มีฟังก์ชั่นไบนารีถึงทศนิยมที่นี่ ทำด้วยตัวคุณเอง!

ฉันกำลังนับบรรทัดใหม่ (ซึ่งฉันคิดว่าจำเป็นต้องได้รับ if-then-else โดยไม่มีEND IF) เป็นหนึ่งไบต์ต่อเมตาโพสต์นี้ ฉันไม่รู้ว่า QB64 บน Windows จะยอมรับไฟล์โค้ดด้วยวิธีนี้หรือไม่ อาจไม่สำคัญมากนัก


2

NodeJS - 62

Buffer(s.split(' ').map(function(a){return parseInt(a,2)}))+''

PHP - 75

array_reduce(explode(' ', $b),function($a,$b){return $a.chr(bindec($b));});

คุณรัน nodejs พร้อมความเข้ากันได้ของ es6 อย่างไร รุ่นล่าสุดยังไม่รองรับฟังก์ชั่นแลมบ์ดาสำหรับฉัน
bebe

ฟังก์ชั่น @bebe Arrow ถูกนำมาใช้ใน v8 แต่ยังไม่ได้รวมกับโหนด ฉันจะแก้ไขโพสต์ของฉัน
cPu1

@ cPu1 พวกเขาทำงานให้ฉัน
username.ak

2

JavaScript 111

นี่เป็นการแปลงตัวเลขโดยไม่มีการแยกวิเคราะห์หรือประเมินผล อ่านสตริงไปข้างหลังและนับบิตมันตั้งค่าบิต x ถ้ามันเป็นหนึ่ง เมื่อพบช่องว่างตัวเลขจะถูกแปลงเป็นอักขระถ่านและหมายเลข 0 ใหม่จะเริ่มขึ้นสำหรับการตั้งค่าบิต

x=n=0,w='',s=' '+s
for(i=s.length;i--;){m=s[i]
if(m==1)n|=1<<x
x++
if(m==' ')w=String.fromCharCode(n)+w,n=x=0
}

1
+1 สำหรับการทำในลักษณะที่ล้าสมัย - เป็นแรงบันดาลใจให้ฉันเขียนรุ่น QBasic ด้วย
DLosc

ไม่ถูกต้องจะต้องมีฟังก์ชั่นหรือโปรแกรมเต็มรูปแบบ (อันที่รับอินพุต)
ASCII- เท่านั้น


2

CJam, 11 ไบต์

NS/{:~2bc}/

sไม่ใช่ชื่อตัวแปรทางกฎหมายใน CJam ดังนั้นฉันจึงเลือกNแทน

ลองออนไลน์

ตัวอย่างการวิ่ง

$ cjam <(echo '
> "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
> :N;
> NS/{:~2bc}/
> '); echo
Hello World

มันทำงานอย่างไร

NS/            " Split N at spaces.                            ";
   {     }/    " For each chunk:                               ";
    :~         "   Evaluate each character ('0' ↦ 0, '1' ↦ 1). ";
      2b       "   Convert from base 2 array to integer.       ";
        c      "   Cast to character.                          ";

2

Haskell - 48 (+13 การนำเข้า (?))

นี่คือความพยายามครั้งแรกของฉันในสนามกอล์ฟ Haskell

map(chr.foldl1((+).(*2)).map digitToInt)$words s

คุณต้องนำเข้า Data.Char

การใช้งาน (ใน ghci):

Prelude> :m +Data.Char
Prelude Data.Char> let s = "1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100"
Prelude Data.Char> map(chr.foldl1((+).(*2)).map digitToInt)$words s
"Hello World"

คำอธิบาย:

map(chr.foldl1((+).(*2)).map digitToInt)$words s
                                        $words s -- split s on spaces into a list
                         map digitToInt          -- convert each digit in input string to int
              ((+).(*2))                         -- a function that multiplies its first 
-- argument by 2, then adds the second argument
        foldl1((+).(*2)).map digitToInt          -- fold the above over the list of ints: 
-- in other words this is a function that reads strings as binary and gives the value as int
   (chr.foldl1((+).(*2)).map digitToInt)         -- cast to character
map(chr.foldl1((+).(*2)).map digitToInt)$words s -- map our function over the list of words

หวังว่าฉันจะทำตามอนุสัญญาให้คะแนนที่ถูกต้องเกี่ยวกับการนำเข้า รู้สึกอิสระที่จะแก้ไขในการแก้ไขถ้าฉันไม่ได้ ฉันปฏิบัติต่อ ": m + Data.Char" จำเป็นต้องนำเข้าใน ghci เมื่อวันที่ 13
ballesta25

1

GNU Sed, 19 ไบต์

แรงบันดาลใจจากคำตอบ @Digital Trauma ที่ยอดเยี่ยม

แข็งแรงเล่นกอล์ฟ

s/\w*/dc -e2i&P;/eg

ทดสอบ

echo 1001000 1100101 1101100 1101100 1101111 100000 1010111 1101111 1110010 1101100 1100100|\
sed 's/\w*/dc -e2i&P;/eg'

Hello World

1

Pyth, 7 ไบต์ (ไม่แข่งขัน)

smCid2c

รับอินพุตเป็นสตริง

ลองมัน!


ทำเครื่องหมายว่าไม่แข่งขันเนื่องจากภาษานั้นใหม่กว่าความท้าทาย
mbomb007

1

05AB1E , 4 ไบต์ (ไม่แข่งขัน)

บันทึกแล้ว 3 ไบต์ขอบคุณ @Emigna

#CçJ

ลองออนไลน์!


1
#CçJยังใช้งานได้ แม้ว่าในทั้งสองนี้และรุ่นของคุณที่คุณต้องการð¡แทน#ถ้าการป้อนข้อมูลสามารถเป็นเพียง 1 อักขระ
Emigna
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.