[Question]
  [
**The input:**
As an example, take a list containing a number of bits (in this case, 32):
```
11000010000100111011000011001011
```
We can calculate a simple [checksum](https://en.wikipedia.org/wiki/Checksum) of this data by dividing it into evenly sized blocks, and taking the XOR of each of them. For example, with eight bit blocks:
```
11000010
00010011
10110000
11001011
10101010
```
We then append this to the end, making it 40 bits:
```
1100001000010011101100001100101110101010
```
This will be the form your input is given in.
To validate a checksum in this form, you just take the XOR of each block, including the checksum. If it's valid, it will result in a string of zeroes.
**The challenge:**
I've got a bunch of data with checksums. The problem is, I don't remember what the block size was! Your task is to write a program or function which takes input of any length, and returns all of the block sizes where the checksum is valid.
Blocks with sizes that do not fit evenly into the input should be ignored (so `7` would not be allowed in the output given `00000000`). In the example above, the valid block sizes would be `[1, 2, 4, 8]`, and the invalid ones would be `[5, 10, 20]`.
Note that block sizes of one are possible (valid if the XOR of every bit in the string results in 0). A block the size of the entire string is not valid (so `8` would not be allowed in the output given `00000000`), and blocks with sizes less than two do not need to be handled.
You can produce output and take input in any reasonable manner, such as lists of bits, strings of `0`s and `1`s, integers representing the binary values, etc.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest answer in bytes per language wins!
**Test cases:**
```
1100100001000000  ->  [1, 2, 4]
010010100100      ->  [1, 2, 3]
0000000000        ->  [1, 2, 5]
101101000         ->  [1, 3]
10010110          ->  [1, 2]
10000000          ->  []
0101010           ->  []
11                ->  [1]
1                 ->  (does not need to be handled)
                  ->  (does not need to be handled)
```
  
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~10~~ 8 bytes
Input is a list of bits.
```
gÑ¨ʒιOÈP
```
[Try it online!](https://tio.run/##yy9OTMpM/f8//fDEQytOTTq30/9wR8D//9EGOoY6BjoQEsEyiAUA "05AB1E – Try It Online")
**Commented**:
```
gÑ          # push the divisors of the length of the input
  ¨         # remove the last one (the length itself)
   ʒ        # filter this list on:
    ι       #   push [a[0::b], a[1::b], ..., a[(b - 1)::b]] where a is the input b the divisor
            #   this groups the digits from each group at the same index together
     O      #   sum each list
      ÈP    #   are all sums even?
```
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~33~~ ~~31~~ ~~28~~ ~~30~~ 33 bytes
```
{((|/2!+/#[;x]0N,)')_&~(!#x)!'#x}
```
[Try it online!](https://ngn.bitbucket.io/k#eJyNjk1qwzAQhfdzimc5VBJ2aslONhHkCLlAMKXFClkUe1EtDGlz9ugnGMfe9I0YZuZjRu9yuAnxW9VZUeVnM7bqVEouP97uIstHmfF8/CMid3jnfCOY1kr590xKMcNUHKV5aCf5xs8jSrWKbSpn2yHCUDNTMp8Yk1QIZy7cSaKKln8C2yNw1iXqEruW5gYQNeON55OAFd+3NJnEkjcBJtdYwTrCl7tPGC2FwApojYXSOU+WIBLRDfYH/eDQW9vBDfiyuH723bftJK1W/rHzABIUYO8=)
Takes input as a list of `0`s and `1`s.
* `&~(!#x)!'#x` divisors of the length of the input
* `((...)')_...` drop records from the right side (divisors) if the left side (run on each divisor) is truthy
* `#[;x]0N,` split the input into equal pieces, each of length corresponding to the current divisor
* `|/2!+/` are there an odd number of 1's in any "column" of the split-out input?
[Answer]
# [Add++](https://github.com/cairdcoinheringaahing/AddPlusPlus), 29 bytes
```
D,g,@@,T2€BbB^
L,bLd1_Rþ%A$þg
```
[Try it online!](https://tio.run/##S0xJKSj4/99FJ13HwUEnxOhR0xqnJKc4Lh@dJJ8Uw/igw/tUHVUO70v/r5KTmJuUkqhgaBdtqGCoYACF6CxDBYgsqhpDuAqEPBzHcvlzIZlugKIabjKGKgyIpsKQgKwhUOQ/AA "Add++ – Try It Online")
I'm surprised Add++ was this short. Takes input as a list of bits
## How it works
```
D,		; Define a helper function
	g,	; called g
	@@,	; that takes 2 arguments e.g. [8 [1 1 0 0 0 0 1 0 0 0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 0]]
	T	; Split into chunks; [[1 1 0 0 0 0 1 0] [0 0 0 1 0 0 1 1] [1 0 1 1 0 0 0 0] [1 1 0 0 1 0 1 1] [1 0 1 0 1 0 1 0]]
	2€Bb	; Convert from binary; [67 200 13 211 85]
	B^	; Reduce by XOR; 0
L,		; Define an unnamed lambda
		; Example argument: [1 1 0 0 0 0 1 0 0 0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 1 1 0 0 1 0 1 1 1 0 1 0 1 0 1 0]
	bL	; Length; 40
	d	; Duplicate; [40 40]
	1_	; Decrement; [40 39]
	R	; Range; [40 [1 2 3 ... 37 38 39]]
	þ%	; Filter false Mod; [1 2 4 5 8 10 20]
	A$	; Push the argument below; [[1 1 0 ... 0 1 0] [1 2 4 5 8 10 20]]
	þg	; Filter false on g; [1 2 4 8]
```
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), 16 bytes
```
⟨{ġ\+ᵐ~×₂ᵐl}ᶠxl⟩
```
[Try it online!](https://tio.run/##SypKTM6ozMlPN/pfXa6koGunoFSu9qhtw6Ompoe7Omsfbp3w/9H8FdVHFsZoA9l1h6eDJLZOyKl9uG1BRc6j@Sv/Y8rpqeXYgeT/R0cb6BjqGOhASATLIFYn2kAHEwKFIQoRyg2gYjAjDJFE4BBsnCHCGrAKw9hYAA "Brachylog – Try It Online")
```
⟨{ġ\+ᵐ~×₂ᵐl}ᶠxl⟩
⟨            x ⟩ remove
              l  the input's length from
 {         }ᶠ    all results of:
  ġ               split the input into equal sized groups
   \              transpose
    +ᵐ            the sum of each column is
      ~×₂ᵐ        the result of a multiplication of some number by 2
          l       get the length of the block
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 12 bytes
```
fö¬ΣFz≠C¹hḊL
```
[Try it online!](https://tio.run/##yygtzv6f@6ip8X/a4W2H1pxb7Fb1qHOB86GdGQ93dPn8//8/OtpAx1DHQAdCIlgGsTrRBjoYECgKUYdQDRODmWCIJIKsD2EDTIUhhISrQmcZwu1BlkG1C8lMsLmxAA "Husk – Try It Online")
```
f               # filter truthy elements x of
          ḊL    # the divisors of the length of the input
         h      # except the last one (the length itself)
                # using this function:
 ö              # apply 4 operations:
  ¬             #   NOT
   Σ            #   the sum of
    F           #   folding each pair of elements by
     z          #     zipping each pair together by
      ≠         #     xor (not equal)
       C¹       #   to the input split into blocks of size x
```
[Answer]
# [Ruby 2.7](https://www.ruby-lang.org/) `-nl`, ~~85~~ 75 bytes
*Saved a whooping 10 bytes, thanks to [Dingus](https://codegolf.stackexchange.com/users/92901/dingus)!*
```
p (1...~/$/).select{|i|~/$/%i+eval($_.scan(/.{#{i}}/).map{|i|i.to_i 2}*?^)<1}
```
[Try it online!](https://tio.run/##RYvRCgIhEEXf/YqFNnCLxpmeg/6kxZZ9EEwlLQjXPj1Ti5p7GeYe7lxv50fOruMEAE/RiwH8rOcpxEUtNa/Vdr5LzfsR/CQNFxBXUaVUihfpaktBsKPq9mlzPA0HSjkTIRZ/FyLDBj6U4W9YYQ3XC1tghP@fKkbE6GVdUNb4vDP6DQ "Ruby – Try It Online")
TIO uses an older version of Ruby, whereas in Ruby 2.7, we've numbered parameters, i.e., `_1`, which saves 2 bytes.
[Answer]
## [SageMath](https://www.sagemath.org/), ~~99~~ 104 bytes
```
f=lambda s:[d for d in divisors(len(s))[:-1]if 0^eval("^".join(["0b"+s[x:x+d]for x in(0,d..len(s)-1)]))]
```
The two instances of the `^` operator here are actually different operators! Sage [preprocesses the source code](https://doc.sagemath.org/html/en/reference/repl/sage/repl/preparse.html) to treat `^` as exponentiation, but `eval` is just ordinary Python eval, which treats `^` as bitwise xor.
The expression `0^X` is used as a shorter way to express `X==0`. It works because 0⁰=1, whereas 0ⁿ=0 for non-zero n. (This trick was used by Julia Robinson in her work on Hilbert’s Tenth Problem, and is employed in the famous paper [*Diophantine representation of the set of prime numbers*](https://www.jstor.org/stable/2318339).)
This function takes its input as a string of zeroes and ones, and returns a list of numbers.
---
**Edit**: Thanks to ovs for pointing out that I had overlooked the part of the problem statement that says blocks the size of the whole string are not allowed.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 11 bytes
```
LÆḌs@^/ẸɗÐḟ
```
[Try it online!](https://tio.run/##y0rNyan8/9/ncNvDHT3FDnH6D3ftODn98ISHO@b/D3vUtOZwu@bRSQ93zvj/X8nQ0AAIYIQhkAsVAfEgfDBU0lFQMoCIgVWC@XAA4oF1ghCEA9YNlUAoQjLN0FAJAA "Jelly – Try It Online")
Input as a list of bits, the Footer does this for you
## How it works
```
LÆḌs@^/ẸɗÐḟ - Main link. Takes a list of bits, B, on the left
L           - Length of B
 ÆḌ         - Proper divisors
        ɗÐḟ - Filter proper divisors k, keeping those which return False:
   s@       -   Split B into pieces of length k
     ^/     -   Reduce columnwise by XOR
       Ẹ    -   Are any true?
```
Monads you could use instead of `Ẹ`:
* `S`: Sum of columns
* `T`: Indexes of non-zero elements
* `Ḅ`: Convert from binary
* `Ḍ`: Convert from decimal
* `Ṭ`: Generate an array which would yield the original argument under `T`
* `Ṁ`: Maximum
* `§`: Sum of rows
[Answer]
# [Perl 5](https://www.perl.org/) `-lF`, 68 bytes
```
map{@a=$i=0;//;map$a[$i++%$']+=$_,@F;@F%$_+(grep$_%2,@a)||say}1..$#F
```
[Try it online!](https://tio.run/##K0gtyjH9/z83saDaIdFWJdPWwFpf3xrIVUmMVsnU1lZVUY/VtlWJ13Fws3ZwU1WJ19ZIL0otUIlXNdJxSNSsqSlOrKw11NNTUXb7/9/Q0AAIYIQhkAsVAfEgfDD8l19QkpmfV/xf19dUD8j/r5vjBgA "Perl 5 – Try It Online")
[Answer]
# [Python 3.8](https://docs.python.org/3.8/), 110 bytes
```
lambda n:(l:=len(n))and[b for b in range(1,l)if not(eval('^'.join('0o'+n[a:a+b]for a in range(0,l,b)))or l%b)]
```
[Try it online!](https://tio.run/##TU/RToQwEHy/r9gXs91cNe1xRkOCP8JhUqB4aC0EqlEJ345t4U63m3Zmmul2@m937mzy2A9Lk50Wo97LWoFNmUkzoy2zRMrWeQlNN0AJrYVB2RfNJDfUNmA7x/SnMgyf8e61ay1D0eHe5ipV@7IIJvVnEtzwkoi8am5KKhanRzdCBgylFML3tgmBHEWUVj3Qa3ni9Xi1YhHpCv@5wwqiRE47/dXryuk6TMslhwOHY8E3lFzR/Yougj/WloV/ozrr6k0P8cOnj8PDsUIOEckEaRfSOq5D3p@2ZzEch8tgSnfgK8RtmKNI@qG1jjU4uRlun2AaZ5i2IfmYZbqYkZZf "Python 3.8 (pre-release) – Try It Online")
Inputs a string of \$1\$s and \$0\$s and returns a list of all possible block sizes where the checksum is valid.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~94~~ 86 bytes
Input is a list of bits.
```
lambda s:[d for d in range(1,len(s))if~-any(len(s)%d+sum(s[x::d])%2for x in range(d))]
```
[Try it online!](https://tio.run/##RY3BCsIwDIbvPkUuYwlOafVW2JPMHSrdtNDVslbYLr56bTtxSQj5v5@fuDU8X/Yax/YWjZzuSoIXnYLxNYMCbWGW9jEgb8xg0RPp8XOSdsVNVuro3xP6bhFC9VRdcmzZY4qoj5mFwYeMa84ZS/NbjAErYKPA/gWJFZwvVgRwtmdyA@f12TujA5I4ABhowWgfcJIOtQ1NeUuULDcnjSMaovgF "Python 3 – Try It Online")
**Commented**:
```
lambda s:[                       ]    # lambda function with a list of digits s as input and a list of integers as output
  d for d in range(1,len(s))          # take the block size d in 1,2,...len(s)-1
    if ~-any(  for x in range(d))     # if for no index in 0,1,...,d-1
      len(s)%d                        #   the block size does not divide the input size
      +sum(s[x::d])%2                 #   or there is an odd number of 1's at this index
```
---
# [Python 3.8](https://docs.python.org/3.8/), 86 bytes
Same length as a recursive function
```
f=lambda s,d=1,x=0:s[d:]and[x][d-x:]+f(s,d+(w:=len(s)%d+sum(s[x::d])%2+x//d>0),~-w*~x)
```
[Try it online!](https://tio.run/##RY3BCsIwDIbvPkUuY4mbmupFCvVFxg6TbjjourJWVi@@@qxTNAk/@b@fEPcIt9Gezm5alk6ZZrjqBnyplSijYukrLevG6irWld5FWRcdprTAWSrTWvSU6cLfB/RVlFLXlB2LeDjoC1P53M3bZ6SlGycIrQ/QW8iFYE7zFWbgFXwo8K8gsRW/N14NCP7fvBuEyPfemT4gyQ2AAQWm9wGHxmFvQ7m@JUqRm5LHDg3R8gI "Python 3.8 (pre-release) – Try It Online")
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 62 bytes
```
sTr/@Mod[i=0;1+##&@@s~Partition~UpTo@i++&/@s,2]~Cases~{1..}
```
[Try it online!](https://tio.run/##TYxBCoMwEEX3HiMBN1pNui2WAemyYKldiYtgU8xCI0kKBTGH6A16wh4h1VRKZ4bPvP@Z6ZhpeceMaJi7ZU6/n69SpXCU10pkZEcjjEMAbQumjDBC9vYylBJEFIUp6Hhb25xpru1Ik2Ryp7vgpiqU6E2FN/sblPLwGBTXer6EvGWKNYYrDbgO7blhvR0DRCkh86xCCIoDRLz3DTz/aqE58eEKxPO6/79Y2tsUBVPtPg "Wolfram Language (Mathematica) – Try It Online")
Input a list of bits.
Xor gives the same result as the sum of its arguments mod 2, but `Xor` is not `Listable`, while `Plus` and `Mod` are.
Mathematica's `Listable` functions only reduce when all arguments are lists of the same length or scalars. Thus if the block size does not evenly divide the total length, so `Plus` remains unevaluated. The resulting expresion `Plus[...]` cannot be matched by `{1..}`.
```
Mod[i=0;1+##&@@s~Partition~UpTo@i++&/@s,2]  (* calculate bitwise complements of possible checksums of the input *)
% ~Cases~{1..}                              (* find those which only contain 1s *)
Tr/@ %                                      (* get the length of each. *)
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 29 bytes
```
ＩΦＬθ∧ι¬∨﹪Ｌθι⌈﹪↨ΣＥ⪪θι⍘λ⊕Ｌθ⊕Ｌθ²
```
[Try it online!](https://tio.run/##dY3NCsIwEIRfJcctRIhePakgCLYKeYIlCW0gP226Fd8@Jv6gF4edgeVbdtSASUV0OV@TDQQHnAmO1pFJcDahpwGmhrNd0GA56yLBJUEb9eLiL7fFLd6tX/yH7nE2IOuOI8jRWYLpdViJpFLXg@PsFFQy3gQy@vux6i/ibNO8tc1ZrEWZZ4i8urkH "Charcoal – Try It Online") Link is to verbose version of code. Explanation: Charcoal has no bitwise Or operator nor an easy way to reduce it over an array so I emulate it by performing a sum using a large base and then separately reducing each digit modulo 2.
```
   θ                            Input string
  Ｌ                             Length
 Φ                              Filter over implicit range
     ι                          Current value (i.e. is non-zero)
    ∧                           Logical And
      ¬                         Logical Not
         Ｌθ                     Length of input string
        ﹪                       Modulo (i.e. does not divide by)
           ι                    Current value
       ∨                        Logical Or
                  θ             Input string
                 ⪪ ι            Split into substrings of current length
                Ｅ               Map over substrings
                     λ          Current substring
                    ⍘           Convert string from base
                      ⊕Ｌθ       Incremented input length
               Σ                Take the sum
              ↨                 Convert to array using base
                         ⊕Ｌθ    Incremented input length
             ﹪              ²   Vectorised modulo by 2
            ⌈                   Take the maximum i.e. are any odd?
Ｉ                               Cast to string
                                Implicitly print
```
[Answer]
# Scala, ~~95~~ 93 bytes
```
b=>1.to(b.size/2)filter{s=>b.grouped(s).reduce((_,_).zipped.map(_^_)).toSet==Set(b.size%s*2)}
```
[Try it online!](https://scastie.scala-lang.org/NkFGxpSqSq6zSwD8vPqwEw)
Accepts input as a list of ints.
`b` is the input block. `1.to(b.size/2)` is a range of all possible block sizes, and `filter{s=>...}` is used to keep only those that divide `b` evenly and that result in a string of zeroes.
`b.grouped(s)` splits `b` into chunks of size `s`, then `reduce` is used to xor all the chunks together. The function to reduce with is `(_,_).zipped.map(_^_)` (the underscores are placeholders for actual parameters). `(_,_).zipped` zips the two lists together, and `map(_^_)` applies xor to each pair in both lists. Finally, `toSet` is invoked on the result of xor-ing the chunks together, so now it's either a `Set(0)` if it had only zeroes, or `Set(1)` or `Set(0,1)` if it had ones.
We can check both that this result is `Set(0)` and that `s` divides `b` evenly by comparing that set with `== Set(b.size % s * 2)`. `b.size % s * 2` will be 0 if `s` divides `b` evenly, but if not, it will be 2 or some higher number, not `1`. The result from earlier can only contain a `0` or `1`, so it will only match if `b.size % s` is `0` and the result from earlier is a `Set` with just a `0`, checking both conditions at once.
[Answer]
# [Pip `-n`](https://github.com/dloscutoff/pip), 31 bytes
```
{!#y%a&!$BX(FB_My<>a)}FI1,--#Ya
```
[Try it online!](https://tio.run/##K8gs@P@/WlG5UjVRTVHFKULDzSnet9LGLlGz1s3TUEdXVzky8f///waGBkAEJgz@6@YBAA "Pip – Try It Online")
Input as a string of 0s and 1s.
## Explanation
```
{!#y%a&!$BX(FB_My<>a)}FI1,--#Ya a → input
                        1,--#Ya range 1..length(a)-1
                             Ya store input in y
{                    }FI        filter each i by the following:
  #y%a                           length(a) mod i
 !                               logical not (is divisor)
      &                          and
                y<>a             input split into chunks of length i
            FB_M                 mapped from binary to decimal
        $BX(        )            folded by bitwise xor
       !                         logical not (checksum validity)
                                 is true?
                                join with newlines(-n flag)
```
[Answer]
# JavaScript (ES10), 94 bytes
Expects a string.
```
s=>(g=k=>s[++k]?[(h=i=>(t=s.substr(i,k))?t[k-1]?'0b'+t^h(i+k):~0:0)(0)?[]:k,g(k)].flat():[])``
```
[Try it online!](https://tio.run/##dc/JDoIwEAbgu0/RcHEmLE5dLiSFB2lqxIXFEjG2evTVEVERFWeaHpqv/7T75JKYzak4Wv9QbXd1KmojIsiEFpGRrqtVLCEXRXNmhQnMeW3sCQpPI8ZWap@reEzrsWuXORSuxvBKISEQxlKF2stAowrSMrGAoVS4WtWb6mCqcheUVQYpOJwTNeu5ETmIbDJhknts6rG5Gn15av3jksOa@vCzX99Vq7/84sc32W38i/f8bABT61@2Hz6E@@/o8NAX7925v5Dzt/kYr@ob "JavaScript (Node.js) – Try It Online")
### Commented
```
s => (                         // s = input string
  g = k =>                     // g is a recursive function taking a block size k
    s[++k] ?                   //   increment k; if s[k] is defined:
      [                        //     begin an array:
        ( h = i =>             //       h is a recursive function taking a counter i
          (t = s.substr(i, k)) //         t is the next substring of maximum size k
          ?                    //         if it's non-empty:
            t[k - 1] ?         //           if the size of t is k:
              '0b' + t         //             convert it from binary to decimal
              ^                //             and XOR it with
              h(i + k)         //             the result of a recursive call to h
            :                  //           else:
              ~0               //             stop and invalidate the final result
                               //             (the length of s is not a multiple of k)
          :                    //         else:
            0                  //           stop
        )(0)                   //       initial call to h with i = 0
        ?                      //       if the result is not 0:
          []                   //         append an empty array (removed by flat())
        :                      //       else:
          k,                   //         append k
        g(k)                   //       append the result of a recursive call to g
      ].flat()                 //     end of array; flatten it
    :                          //   else:
      []                       //     stop
)``                            // initial call to g with k zero'ish
```
[Answer]
# [R](https://www.r-project.org/), 93 bytes
```
function(x,l=sum(x|1))which(!sapply(seq(l=l-1),function(n)l%%n|any(rowSums(matrix(x,n))%%2)))
```
[Try it online!](https://tio.run/##jZDtCoIwFIb/exWLEM6BBU4L@uNVdAFiZjiamzlNDe/dDPOrIGVsHNh59j47afPwBb94Z6GCm6f5M9Ruc81lkHEloaTC1XkMZc0Qi4gHEWy0nySiAh3eQbhix5AO7RKFacralxWkqjjlsYbYz1Jetg9JRNO0EbHJQp25AViUUYt251hZaPwIwZtAsiWM2MQxBv5nLbGHnu0yx@QF0plyvTFbzJtTqyylkqExG9Bnr4Var79Wk77B6Ltiw2ymN/O/T9RWTILsydFoXg "R – Try It Online")
For each `n` up to the length of the input minus 1, rearranges the input bits into a matrix with `n` rows: the checksum is valid if the sum of every row is an even number.
[Answer]
# [Julia](http://julialang.org/), 71 bytes
```
a->filter(i->L%i<1&&!any(xor(a[j:i:L]...) for j=1:i),1:(L=length(a))-1)
```
expects an `Array{Bool}`
[Try it online!](https://tio.run/##bZDPToQwEIfvfYqx0d02AdK6eiHCwZsJb4AcyG6rQ5qygZrgc5h48ul8EaRlXdhk@@/yffObZpoPg7UcRp2NdZxrNE51DOO8uMMnudnc1PaTDW3H6rJJMS2qJEk46LaDJpMp8kimrMiMsm/undWcx5KPTvWuhwxKQqUUYjqnRwgKkOUApYzgPoKHilARjFmbqF8rY@eN8zrxC@NxMqb6ELEIZ2MXsAjGQpeAGV@mz/jFunL@n98ruKZSrsEquiIVIcTPiWHUcEALYSyEeEfjNB7NntvWJGzfGqP2jiGHJIat2HIeJNTBy6Ah/9nHDq0zltHfny@gEaDvpnH2lenVNfN7ZUZAXx1Tw3FqqA5w23B6KrYH4u/4Bw "Julia 1.0 – Try It Online")
[Answer]
# [Haskell](https://www.haskell.org/), 109 bytes
```
f s=[x|x<-[1..l s-1],rem(l s)x==0,not.or.foldr1(zipWith(/=))$x#map(=='1')s]
l=length
_#[]=[]
n#x=x:n#drop n x
```
[Try it online!](https://tio.run/##XY7BasQgFEX3@YpHMjAKjtVOuynzvqMLkRJI0kiNkehChv57atI0dKIics99B/s6fLXWznMHAVX6TreLkpxbCBep2dQOJD9pQhTMjZGPE@9G20yS3I1/N7EnT0jpKVVD7QniWZ5p0IVF27rP2BcfldKodOGqhOnNVc00enCQ5qE2DhD8ZFwEDpsMSHZQHlxDwTgPJ8haIF1udCGuWbHkCIqUUgqRz3YJUTIlGTwzeNG0gHUxUoq19VvdG9eHxr52/vqf5@lVsOHrIxMr3iYP6E96@M@yD6mUi2FP9PwD "Haskell – Try It Online")
If taking the input as a list of booleans counts as a reasonable manner it would go down to 99 (not sure if it does, though):
# [Haskell](https://www.haskell.org/), 99 bytes
```
f s=[x|x<-[1..l s-1],rem(l s)x==0,not.or.foldr1(zipWith(/=))$x#s]
l=length
_#[]=[]
n#x=x:n#drop n x
```
[Try it online!](https://tio.run/##XY7BasQgEIbveYohWVgF12q3vZSd5@hBpASSNFJjJHqQpe@emjQN3Ywiw3zf/NjX4au1dp47CKjSd7pdlOTcQrhIzaZ2ILmlCVEwN0Y@TrwbbTNJcjf@3cSePCGlp1QFXVi0rfuMffFRKY1KF65KmN5c1UyjBwdpHmrjAMFPxkXgsEUAIYiUB9dQMM7DCYbaA@mykZvMzvJMeRfiiotFQVCklFKIfLdHiJIpyeCZwYumBazFSClW61fdjeuDsdfOX//zvL0GbPj6yMSKt80D@gs9/Gc5h6mUS8I@0fMP "Haskell – Try It Online")
]