Recursive subdivision is one simple and guaranteed finite-time solution, though it tends to look a little... non-uniform. The end result is reminiscent a bit of a mondrian painting and doesn't look exactly like random scattered rectangles. If that's still good enough for you, the algorithm is:
makeRects(x, y, width, height) if shouldSubdivide(width * height) then // pick which way to split it, tend towards making // the resulting pieces closer to square if random(width + height) < width then // split vertically var split = random(width) makeRects(x, y, split, height) makeRects(x + split, y, width - split, height) else // split horizontally var split = random(height) makeRects(x, y, width, split) makeRects(x, y + split, width, height - split) end else // not splitting the box, so just draw a rectangle inside it randomRect(x, y, width, height) end end // randomly inset the rect within the given bounds randomRect(x, y, width, height) var insetWidth = random(width) var insetHeight = random(height) var insetX = random(width - insetWidth) var insetY = random(height - insetHeight) placeRect(x, y, width, height) end // determine if a rect of the given area should be // subdivided, or if its small enough that we should // stop here shouldSubdivide(area) // return true or false. the smaller the area, the more // likely to be false. tune to taste... end random(max) // generate random value between 0 and max... end placeRect(x, y, width, height) // do whatever you want here to place the rect... end