กำหนดเขตข้อมูลด้วยองค์ประกอบ 256


15

ฟิลด์ในวิชาคณิตศาสตร์เป็นชุดของตัวเลขที่มีการเพิ่มและการคูณการดำเนินงานที่กำหนดไว้ในนั้นเช่นที่พวกเขาตอบสนองหลักการบางอย่าง (ที่อธิบายไว้ในวิกิพีเดียดูยังด้านล่าง)

เขตข้อมูล จำกัด สามารถมีองค์ประกอบp nซึ่งpเป็นจำนวนเฉพาะและnเป็นจำนวนธรรมชาติ ในการท้าทายนี้ลองทำp = 2และn = 8ทำฟิลด์กับ 256 องค์ประกอบ

องค์ประกอบของฟิลด์ควรเป็นจำนวนเต็มต่อเนื่องในช่วงที่มี0และ1:

  • -128 ... 127
  • 0 ... 255
  • หรือช่วงอื่น ๆ

กำหนดสองฟังก์ชั่น (หรือโปรแกรมถ้าทำได้ง่ายกว่า) a(x,y)สำหรับนามธรรม "การเพิ่ม" และm(x,y)สำหรับ "การคูณ" แบบนามธรรมเพื่อให้เป็นไปตามความจริงของสนาม

  • ความสอดคล้อง: a(x,y)และm(x,y)สร้างผลลัพธ์เดียวกันเมื่อถูกเรียกด้วยอาร์กิวเมนต์เดียวกัน
  • Closedness: ผลลัพธ์ของaและmเป็นจำนวนเต็มในช่วงที่เกี่ยวข้อง
  • associativity: สำหรับการใด ๆx, yและzอยู่ในช่วงที่a(a(x,y),z)จะมีค่าเท่ากับa(x,a(y,z)); เหมือนกันสำหรับm
  • Commutativity: สำหรับใด ๆxและyในช่วงa(x,y)เท่ากับa(y,x); เหมือนกันสำหรับm
  • distributivity: สำหรับการใด ๆx, yและzอยู่ในช่วงที่m(x,a(y,z))จะมีค่าเท่ากับa(m(x,y),m(x,z))
  • องค์ประกอบที่เป็นกลาง: สำหรับใด ๆxในช่วงa(0,x)เท่ากับxและm(1,x)เท่ากับx
  • การปฏิเสธ: สำหรับสิ่งใด ๆxในช่วงนั้นมีอยู่yนั่นa(x,y)คือ0
  • ผกผัน: สำหรับการใด ๆx≠0ในช่วงที่มีอยู่เช่นyที่m(x,y)เป็น1

ชื่อaและmเป็นเพียงตัวอย่าง คุณสามารถใช้ชื่ออื่นหรือฟังก์ชั่นที่ไม่มีชื่อ คะแนนคำตอบของคุณคือผลรวมของความยาวไบต์สำหรับและam

หากคุณใช้ฟังก์ชั่นในตัวโปรดอธิบายด้วยคำที่เป็นผลลัพธ์ (เช่นจัดเตรียมตารางสูตรคูณ)


3
@LeakyNun "การเพิ่ม" เป็นเพียงการดำเนินการเชิงนามธรรมที่นี่ซึ่งเป็นไปตามคุณสมบัติข้างต้น ไม่จำเป็นต้องทำa(2,1) = 3คุณอาจมีa(2,1) = 5ตราบเท่าที่หลักการข้างต้นมีความพึงพอใจ aไม่ต้องทำอะไรด้วยการเพิ่มตามปกติที่คุณคุ้นเคยเช่นจากฟิลด์ของจำนวนตรรกยะ
Martin Ender

2
แหวนสับเปลี่ยนเป็นเรื่องเล็กน้อย เขตข้อมูล ... ไม่ใช่เรื่องง่าย
Neil

มีอะไรผิดปกติa=+ m=×หรือไม่?
Adám

4
@ Adámใช่ - 2 จะไม่ตรงกันข้ามถ้าm=×
Sp3000

คำตอบ:


4

Intel x86-64 + AVX-512 + GFNI, 11 ไบต์

add:
    C5 F0 57 C0     # vxorps     xmm0, xmm1, xmm0
    C3              # ret
mul:
    C4 E2 79 CF C1  # vgf2p8mulb xmm0, xmm0, xmm1
    C3              # ret

ใช้GF2P8MULBคำสั่งใหม่ในซีพียู Ice Lake

คำสั่งคูณองค์ประกอบในฟิลด์ จำกัด GF (2 8 ), ทำงานบนไบต์ (องค์ประกอบฟิลด์) ในตัวถูกดำเนินการแหล่งแรกและไบต์ที่สอดคล้องกันในตัวถูกดำเนินการแหล่งที่สอง ฟิลด์ GF (2 8 ) แสดงด้วยพหุนามแทนด้วยพหุนามลด x 8 + x 4 + x 3 + x + 1


13

Python 2, 11 + 45 = 56 ไบต์

การเพิ่ม (11 ไบต์):

int.__xor__

การคูณ (45 ไบต์):

m=lambda x,y:y and m(x*2^x/128*283,y/2)^y%2*x

[0 ... 255]ใช้เวลาใส่ตัวเลขในช่วง นอกจากเป็นเพียงบิต XOR คูณคูณของพหุนามที่มีสัมประสิทธิ์ใน GF2 กับชาวนารัสเซีย

และสำหรับการตรวจสอบ:

a=int.__xor__
m=lambda x,y:y and m(x*2^x/128*283,y/2)^y%2*x

for x in range(256):
    assert a(0,x) == a(x,0) == x
    assert m(1,x) == m(x,1) == x

    assert any(a(x,y) == 0 for y in range(256))

    if x != 0:
        assert any(m(x,y) == 1 for y in range(256))

    for y in range(256):
        assert 0 <= a(x,y) < 256
        assert 0 <= m(x,y) < 256
        assert a(x,y) == a(y,x)
        assert m(x,y) == m(y,x)

        for z in range(256):
            assert a(a(x,y),z) == a(x,a(y,z))
            assert m(m(x,y),z) == m(x,m(y,z))
            assert m(x,a(y,z)) == a(m(x,y), m(x,z))

เราคนหนึ่งต้องเปลี่ยน: P
Mego

@Mego Hah ดี ... ฉันจะลองดูว่าฉันสามารถหาวิธีการอื่น ๆ อาจเป็นเรื่องยากที่จะเอาชนะ
Sp3000

1
พหุนามแบบใดที่มีพื้นฐานมาจาก?
feersum

1
@LSpice ตอนนี้ฉันรู้ว่าฉันสามารถค้นหาพหุนามโดยการทำงานm(2,128)ซึ่งผลใน 27 = 283-256 x^8 + x^4 + x^3 + x + 1เพื่อให้คุณมีที่ถูกต้องและพหุนามมี
feersum

1
@LSpice ในคำตอบของ Neil เขาให้หน้า Wikipedia เป็นแหล่งข้อมูลสำหรับอัลกอริทึมดังนั้นทุกคนอาจอ่าน แต่มันก็เป็นตัวเลือกที่ชัดเจนที่สุดสำหรับการแข่งขันกอล์ฟโคดเพราะมันเป็นพหุนามลดขนาดเล็กที่สุดในระดับ 8 ในการเป็นตัวแทนนี้
feersum

6

JavaScript (ES6), 10 + 49 = 59 ไบต์

a=(x,y)=>x^y
m=(x,y,p=0)=>x?m(x>>1,2*y^283*(y>>7),p^y*(x&1)):p

โดเมนคือ ... 0 255 แหล่งที่มา


2
คุณควรระบุช่วงที่คุณใช้
Martin Ender

4

ฮุน 22 ไบต์

[dif pro]:(ga 8 283 3)

Hoon มีฟังก์ชั่น++gaที่สร้าง Galois Fields สำหรับใช้ในการนำ AES ไปใช้งาน สิ่งนี้จะคืนค่า tuple ของสองฟังก์ชันแทนที่จะใช้สองโปรแกรม

ดำเนินการในโดเมน [0...255]

TestSuite:

=+  f=(ga 8 283 3)
=+  n=(gulf 0 255)

=+  a=dif:f
=+  m=pro:f

=+  %+  turn  n
    |=  x/@
    ?>  =((a 0 x) x)
    ?>  =((m 1 x) x)
    ~&  outer+x

    %+  turn  n
      |=  y/@
      ?>  =((a x y) (a y x))
      ?>  &((lte 0 (a x y)) (lte (a x y) 255))
      ?>  &((lte 0 (m x y)) (lte (m x y) 255))

      %+  turn  n
        |=  z/@
        ?>  =((a (a x y) z) (a x (a y z)))
        ?>  =((m x (a y z)) (a (m x y) (m x z)))
        ~
"ok"

การโพสต์ตารางสูตรคูณจะมีขนาดมหึมาดังนั้นต่อไปนี้เป็นตัวอย่างแบบสุ่ม:

20x148=229
61x189=143
111x239=181
163x36=29
193x40=1

1

รหัสเครื่อง IA-32 ขนาด 22 ไบต์

"การคูณ", 18 ไบต์:

33 c0 92 d1 e9 73 02 33 d0 d0 e0 73 02 34 1b 41
e2 f1

"การเพิ่ม", 4 ไบต์:

92 33 c1 c3

สิ่งนี้ยืดกฏเล็กน้อย: รหัส "การคูณ" ขาดฟังก์ชั่นรหัสออก มันต้องอาศัยรหัส "การเพิ่ม" ที่อยู่ในหน่วยความจำในเวลาต่อมาดังนั้นจึงสามารถ "ตกลง" ได้ ฉันทำเพื่อลดขนาดรหัส 1 ไบต์

รหัสที่มา (สามารถประกอบโดยmlMS Visual Studio):

    TITLE   x

PUBLIC @m@8
PUBLIC @a@8

_TEXT   SEGMENT USE32
@m@8    PROC
    xor eax, eax;
    xchg eax, edx;
myloop:
    shr ecx, 1
    jnc sk1
    xor edx, eax
sk1:
    shl al, 1
    jnc sk2
    xor al, 1bh
sk2:
    inc ecx
    loop myloop
@m@8 endp

@a@8 proc
    xchg eax, edx;
    xor eax, ecx
    ret
@a@8    ENDP
_text ENDS
END

ขั้นตอนวิธีการเป็นหนึ่งในมาตรฐานที่เกี่ยวข้องกับการพหุนามปกติแทนด้วยจำนวนฐานสิบหกx^8 + x^4 + x^3 + x + 1 1b"การคูณ" edxรหัสสะสมผลใน เมื่อเสร็จแล้วมันจะผ่านไปยังรหัสเพิ่มเติมซึ่งย้ายไปที่eax(การลงทะเบียนทั่วไปเพื่อเก็บค่าตอบแทน); xorกับecxเป็น no-op เพราะที่จุดที่ecxมีการล้าง

คุณสมบัติพิเศษอย่างหนึ่งคือการวนซ้ำ แทนที่จะตรวจสอบค่าศูนย์

cmp ecx, 0
jne myloop

มันใช้loopคำสั่งเฉพาะ แต่คำสั่งนี้จะลดลูป "ตัวนับ" ก่อนที่จะเปรียบเทียบกับ 0 เพื่อชดเชยสิ่งนี้รหัสจะเพิ่มขึ้นก่อนที่จะใช้loopคำสั่ง


0

Mathematica 155 ไบต์

f[y_]:=Total[x^Reverse@Range[0,Log[2,y]]*RealDigits[y,2][[1]]];o[q_,c_,d_]:=FromDigits[Reverse@Mod[CoefficientList[PolynomialMod[q[f@c,f@d],f@283],x],2],2]

การดำเนินงาน

(*
  in: o[Times, 202, 83]    out: 1
  in: o[Plus, 202, 83]     out: 153
*)

ตรวจสอบเพิ่มเติม:

(*
  in: BitXor[202, 83]      out: 153
*)

มากกว่า:

(*
  in: o[Times, #, #2] & @@@ {{20, 148}, {61, 189}, {111, 239}, {163, 36}, {193, 40}}
  out: {229, 143, 181, 29, 1}
*)

NB ควรจะสามารถใช้ใด ๆ ของในสถานที่ของ{283, 285, 299, 301, 313, 319, 333, 351, 355, 357, 361, 369, 375, 379, 391, 395, 397, 415, 419, 425, 433, 445, 451, 463, 471, 477, 487, 499, 501, 505}283


ดีนี่น้อยกว่า 13 ไบต์: ±y_:=Total[#&@@y~RealDigits~2x^Reverse@Range[0,2~Log~y]];p[q_,c_,d_]:=Fold[#+##&,Reverse@CoefficientList[q[±c,±d]~PolynomialMod~±283,x]~Mod~2](สมมติว่าแหล่งที่มาถูกเข้ารหัสใน ISO 8859-1)
Martin Ender

@MartinEnder ไม่แน่ใจว่าจะใช้ข้อเสนอแนะของคุณอย่างไร
martin

@martin คุณสามารถใช้งานได้เหมือนเดิมฉันเพิ่งใช้±แทนfและpแทนo(แน่นอนว่าคุณสามารถเก็บไว้เป็นoฉันใช้pดังนั้นฉันสามารถทดสอบพวกเขาทั้งสอง) และจากนั้นบันทึกสองสามไบต์มาตรฐาน กลเม็ดน้ำตาล
Martin Ender

@MartinEnder จะได้รับ±ในการทำงานเช่นเดียวกับที่fแต่ไม่ได้p... ไม่แน่ใจว่าฉันกำลังจะผิด
มาร์ติน

หากคุณคัดลอกโดยตรงจากความคิดเห็นอาจมีอักขระที่ไม่สามารถพิมพ์ได้ทุกที่ที่เบราว์เซอร์ของคุณแสดงเส้นแบ่งในความคิดเห็น ลบอักขระรอบ ๆ ตำแหน่งนั้นหลังจากทำการคัดลอกแล้วพิมพ์ซ้ำอีกครั้ง หากไม่เป็นเช่นนั้นฉันก็ไม่แน่ใจว่าปัญหาอยู่ตรงไหน ..
Martin Ender

-1

Brainfuck, 28 ตัวอักษร

โชคดีที่ Brainfuck มาตรฐานทำทุกอย่างแบบโมดูโล 256

เพิ่มเติม: [->+<]สมมติว่าอินพุตอยู่ในตำแหน่งสองตำแหน่งแรกของเทปวางเอาต์พุตในตำแหน่ง 0

การคูณ: [->[->+>+<<]>[-<+>]<<]สมมติว่าอินพุตอยู่ในตำแหน่งสองตำแหน่งแรกของเทปวางเอาต์พุตในตำแหน่ง 3

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