Câu hỏi rất thú vị, và mẹo thông minh.
Hãy xem xét một ví dụ đơn giản về việc thao tác một byte đơn. Sử dụng 8 bit không dấu để đơn giản. Hãy tưởng tượng số của bạn là xxaxxbxx
và bạn muốn ab000000
.
Giải pháp bao gồm hai bước: một mặt nạ bit, tiếp theo là nhân. Mặt nạ bit là một hoạt động đơn giản VÀ biến các bit không thú vị thành số không. Trong trường hợp trên, mặt nạ của bạn sẽ được 00100100
và kết quả 00a00b00
.
Bây giờ là phần khó: biến điều đó thành ab......
.
Phép nhân là một loạt các hoạt động thay đổi và thêm. Điều quan trọng là cho phép tràn để "dịch chuyển" các bit mà chúng ta không cần và đặt các bit chúng ta muốn vào đúng vị trí.
Phép nhân với 4 ( 00000100
) sẽ thay đổi mọi thứ còn lại bằng 2 và đưa bạn đến a00b0000
. Để b
di chuyển lên, chúng ta cần nhân với 1 (để giữ a ở đúng vị trí) + 4 (để di chuyển b lên). Tổng này là 5, và kết hợp với 4 trước đó, chúng ta có được số ma thuật là 20, hoặc 00010100
. Bản gốc là 00a00b00
sau khi đắp mặt nạ; phép nhân cho:
000000a00b000000
00000000a00b0000 +
----------------
000000a0ab0b0000
xxxxxxxxab......
Từ phương pháp này, bạn có thể mở rộng đến số lượng lớn hơn và nhiều bit hơn.
Một trong những câu hỏi bạn đặt ra là "điều này có thể được thực hiện với bất kỳ số bit nào không?" Tôi nghĩ câu trả lời là "không", trừ khi bạn cho phép một vài thao tác che giấu, hoặc một vài phép nhân. Vấn đề là vấn đề "va chạm" - ví dụ: "b đi lạc" trong vấn đề trên. Hãy tưởng tượng chúng ta cần phải làm điều này đến một số như thế xaxxbxxcx
. Theo cách tiếp cận trước đó, bạn sẽ nghĩ rằng chúng tôi cần {x 2, x {1 + 4 + 16}} = x 42 (oooh - câu trả lời cho mọi thứ!). Kết quả:
00000000a00b00c00
000000a00b00c0000
0000a00b00c000000
-----------------
0000a0ababcbc0c00
xxxxxxxxabc......
Như bạn có thể thấy, nó vẫn hoạt động, nhưng "chỉ". Chìa khóa ở đây là có "đủ không gian" giữa các bit mà chúng ta muốn mà chúng ta có thể ép mọi thứ lên. Tôi không thể thêm bit thứ tư ngay sau c, vì tôi sẽ nhận được các trường hợp tôi nhận được c + d, bit có thể mang, ...
Vì vậy, nếu không có bằng chứng chính thức, tôi sẽ trả lời các phần thú vị hơn trong câu hỏi của bạn như sau: "Không, điều này sẽ không hoạt động đối với bất kỳ số bit nào. Để trích xuất N bit, bạn cần khoảng trống (N-1) giữa các bit bạn muốn giải nén hoặc có các bước nhân mặt nạ bổ sung. "
Ngoại lệ duy nhất tôi có thể nghĩ đến cho quy tắc "phải có (N-1) giữa các bit" là: nếu bạn muốn trích xuất hai bit liền kề nhau trong bản gốc, VÀ bạn muốn giữ chúng trong cùng một thứ tự, sau đó bạn vẫn có thể làm điều đó. Và với mục đích của quy tắc (N-1), chúng được tính là hai bit.
Có một cái nhìn sâu sắc khác - lấy cảm hứng từ câu trả lời của @Ternary bên dưới (xem bình luận của tôi ở đó). Đối với mỗi bit thú vị, bạn chỉ cần có nhiều số không ở bên phải của nó vì bạn cần không gian cho các bit cần đến đó. Nhưng ngoài ra, nó cần nhiều bit ở bên trái vì nó có các bit kết quả ở bên trái. Vì vậy, nếu một bit b kết thúc ở vị trí m của n, thì nó cần phải có các số 0 m-1 ở bên trái của nó, và các số 0 ở bên phải của nó. Đặc biệt là khi các bit không theo cùng thứ tự trong số ban đầu như sau khi sắp xếp lại, đây là một cải tiến quan trọng đối với các tiêu chí ban đầu. Điều này có nghĩa là, ví dụ, một từ 16 bit
a...e.b...d..c..
Có thể chuyển sang
abcde...........
mặc dù chỉ có một khoảng cách giữa e và b, hai giữa d và c, ba giữa hai cái khác. Chuyện gì đã xảy ra với N-1 ?? Trong trường hợp này, a...e
trở thành "một khối" - chúng được nhân với 1 để kết thúc ở đúng nơi, và vì vậy "chúng tôi đã nhận e miễn phí". Điều này cũng đúng với b và d (b cần ba khoảng trắng ở bên phải, d cần ba khoảng trắng ở bên trái). Vì vậy, khi chúng tôi tính toán số ma thuật, chúng tôi thấy có những bản sao:
a: << 0 ( x 1 )
b: << 5 ( x 32 )
c: << 11 ( x 2048 )
d: << 5 ( x 32 ) !! duplicate
e: << 0 ( x 1 ) !! duplicate
Rõ ràng, nếu bạn muốn những con số này theo một thứ tự khác, bạn sẽ phải sắp xếp chúng thêm nữa. Chúng ta có thể định dạng lại (N-1)
quy tắc: "Nó sẽ luôn hoạt động nếu có ít nhất (N-1) khoảng cách giữa các bit; hoặc, nếu biết thứ tự các bit trong kết quả cuối cùng, thì nếu một bit b kết thúc ở vị trí m của n, nó cần phải có các số 0 m ở bên trái và các số 0 ở bên phải. "
@Ternary chỉ ra rằng quy tắc này không thực sự hiệu quả, vì có thể thực hiện từ các bit thêm "ngay bên phải của khu vực mục tiêu" - cụ thể là khi các bit chúng ta tìm kiếm đều là các bit. Tiếp tục ví dụ tôi đã đưa ra ở trên với năm bit được đóng gói chặt chẽ trong một từ 16 bit: nếu chúng ta bắt đầu bằng
a...e.b...d..c..
Để đơn giản, tôi sẽ đặt tên cho các vị trí bit ABCDEFGHIJKLMNOP
Toán học chúng ta sẽ làm là
ABCDEFGHIJKLMNOP
a000e0b000d00c00
0b000d00c0000000
000d00c000000000
00c0000000000000 +
----------------
abcded(b+c)0c0d00c00
Cho đến bây giờ, chúng tôi nghĩ rằng bất cứ điều gì bên dưới abcde
(vị trí ABCDE
) sẽ không quan trọng, nhưng thực tế, như @Ternary đã chỉ ra, nếu b=1, c=1, d=1
sau đó (b+c)
tại vị trí G
sẽ gây ra một chút để mang đến vị trí F
, điều đó có nghĩa là (d+1)
ở vị trí F
sẽ mang một chút vào E
- và của chúng tôi kết quả là hư hỏng Lưu ý rằng không gian bên phải của bit quan tâm ít nhất ( c
trong ví dụ này) không thành vấn đề, vì phép nhân sẽ gây ra đệm với các số không từ beyone bit ít quan trọng nhất.
Vì vậy, chúng ta cần sửa đổi quy tắc (m-1) / (nm) của mình. Nếu có nhiều hơn một bit có "chính xác (nm) bit không được sử dụng ở bên phải (không tính bit cuối cùng trong mẫu -" c "trong ví dụ trên), thì chúng ta cần tăng cường quy tắc - và chúng ta phải làm như vậy lặp đi lặp lại!
Chúng ta không chỉ nhìn vào số bit đáp ứng tiêu chí (nm), mà cả số bit đang ở (n-m + 1), v.v. Hãy gọi số của chúng là Q0 (chính xác n-m
đến bit tiếp theo), Q1 ( n-m + 1), tối đa Q (N-1) (n-1). Sau đó, chúng tôi có nguy cơ thực hiện nếu
Q0 > 1
Q0 == 1 && Q1 >= 2
Q0 == 0 && Q1 >= 4
Q0 == 1 && Q1 > 1 && Q2 >=2
...
Nếu bạn nhìn vào điều này, bạn có thể thấy rằng nếu bạn viết một biểu thức toán học đơn giản
W = N * Q0 + (N - 1) * Q1 + ... + Q(N-1)
và kết quả là W > 2 * N
, sau đó bạn cần tăng tiêu chí RHS thêm một chút để (n-m+1)
. Tại thời điểm này, hoạt động là an toàn miễn là W < 4
; nếu điều đó không hiệu quả, hãy tăng thêm tiêu chí, v.v.
Tôi nghĩ rằng làm theo những điều trên sẽ giúp bạn có một câu trả lời dài ...